diff --git a/.github/workflows/cpp.yml b/.github/workflows/cpp.yml index 1c5e62f50..7448d3878 100644 --- a/.github/workflows/cpp.yml +++ b/.github/workflows/cpp.yml @@ -43,6 +43,7 @@ jobs: $ENV:CFLAGS='-I C:\vcpkg\installed\x64-windows\include'; $ENV:LDFLAGS='-L C:\vcpkg\installed\x64-windows\lib'; $ENV:CXX='clang++'; $ENV:EXEC_SUFFIX='.exe'; $ENV:WITH_LIBUV='1'; nmake + cmake -G "NMake Makefiles" -B build -S . ls - name: Run smoke test run: | diff --git a/CMakeLists.txt b/CMakeLists.txt index f3ec2b8d7..2b9bb9e98 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,10 +1,7 @@ cmake_minimum_required(VERSION 3.10) -# If project is not already defined, define it (for monorepo) -if (NOT CMAKE_PROJECT_NAME) - project(uWebSockets) -endif() -message(STATUS "Building uWebSockets") +project(uWebSockets) +message(STATUS "Building ${PROJECT_NAME}") # Compiler flags set(CMAKE_CXX_STANDARD 20) @@ -84,9 +81,10 @@ set(EXAMPLE_FILES "CachingApp" "HelloWorldThreaded" "Http3Server" "Broadcast" "H string(STRIP "${LDFLAGS_UWS}" LDFLAGS_STRIPPED_UWS) # Strip leading/trailing whitespace foreach(EXAMPLE_FILE IN LISTS EXAMPLE_FILES) - add_executable(${EXAMPLE_FILE} examples/${EXAMPLE_FILE}.cpp) - target_link_libraries(${EXAMPLE_FILE} uSockets ${LDFLAGS_STRIPPED_UWS}) - target_compile_options(${EXAMPLE_FILE} PRIVATE ${CXXFLAGS}) + set(target_name ${PROJECT_NAME}${EXAMPLE_FILE}) + add_executable(${target_name} examples/${EXAMPLE_FILE}.cpp) + target_link_libraries(${target_name} uSockets ${LDFLAGS_STRIPPED_UWS}) + target_compile_options(${target_name} PRIVATE ${CXXFLAGS}) endforeach() @@ -99,4 +97,10 @@ install(DIRECTORY src/ DESTINATION ${CMAKE_INSTALL_PREFIX}/include/uWebSockets) # Default target is all add_custom_target(all_examples DEPENDS ${EXAMPLE_FILES}) -#add_subdirectory(benchmarks) \ No newline at end of file +add_subdirectory(tests) +add_subdirectory(benchmarks) +# If linux, add epoll benchmarker +if (UNIX AND NOT APPLE) + add_subdirectory(libEpollBenchmarker) +endif () + diff --git a/benchmarks/CMakeLists.txt b/benchmarks/CMakeLists.txt new file mode 100644 index 000000000..832e63bf5 --- /dev/null +++ b/benchmarks/CMakeLists.txt @@ -0,0 +1,47 @@ +cmake_minimum_required(VERSION 3.16) +project(uWebSocketsBenchmarks) +message(STATUS "Building ${PROJECT_NAME}") + +# Set C and C++ standards +set(CMAKE_C_STANDARD 11) +set(CMAKE_CXX_STANDARD 17) + +# Enable LTO if supported +include(CheckIPOSupported) +check_ipo_supported(RESULT lto_supported OUTPUT error) +if(lto_supported) + set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) +else() + message(WARNING "IPO / LTO is not supported: ${error}") +endif() + +# Compile options: enable optimizations, march=native +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_CXX_FLAGS}") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -march=native") + +# Add uSockets include directory +include_directories(${CMAKE_SOURCE_DIR}/libs/uWebSockets/uSockets/src) + +# Define the parser executable +add_executable(${PROJECT_NAME}parser parser.cpp) +target_compile_options(${PROJECT_NAME}parser PRIVATE -flto) +target_link_options(${PROJECT_NAME}parser PRIVATE -flto) + +# Compile tests with uSockets +add_executable(${PROJECT_NAME}broadcast_test broadcast_test.c) +target_compile_definitions(${PROJECT_NAME}broadcast_test PRIVATE -DLIBUS_USE_OPENSSL) +target_link_libraries(${PROJECT_NAME}broadcast_test ssl crypto ${LDFLAGS_STRIPPED_UWS} uSockets) +target_compile_options(${PROJECT_NAME}broadcast_test PRIVATE -flto) +target_link_options(${PROJECT_NAME}broadcast_test PRIVATE -flto) + +add_executable(${PROJECT_NAME}load_test load_test.c) +target_compile_definitions(${PROJECT_NAME}load_test PRIVATE -DLIBUS_USE_OPENSSL) +target_link_libraries(${PROJECT_NAME}load_test ssl crypto ${LDFLAGS_STRIPPED_UWS} uSockets) +target_compile_options(${PROJECT_NAME}load_test PRIVATE -flto) +target_link_options(${PROJECT_NAME}load_test PRIVATE -flto) + +add_executable(${PROJECT_NAME}scale_test scale_test.c) +target_compile_definitions(${PROJECT_NAME}scale_test PRIVATE -DLIBUS_USE_OPENSSL) +target_link_libraries(${PROJECT_NAME}scale_test ssl crypto ${LDFLAGS_STRIPPED_UWS} uSockets) +target_compile_options(${PROJECT_NAME}scale_test PRIVATE -flto) +target_link_options(${PROJECT_NAME}scale_test PRIVATE -flto) diff --git a/benchmarks/load_test.c b/benchmarks/load_test.c index ff7b7c1cd..b12f110d7 100644 --- a/benchmarks/load_test.c +++ b/benchmarks/load_test.c @@ -19,8 +19,30 @@ #define htole64(x) OSSwapHostToLittleInt64(x) #define be64toh(x) OSSwapBigToHostInt64(x) #define le64toh(x) OSSwapLittleToHostInt64(x) -#else + +#elif defined(_WIN32) +#include + +#define htobe16(x) _byteswap_ushort(x) +#define htole16(x) (x) +#define be16toh(x) _byteswap_ushort(x) +#define le16toh(x) (x) + +#define htobe32(x) _byteswap_ulong(x) +#define htole32(x) (x) +#define be32toh(x) _byteswap_ulong(x) +#define le32toh(x) (x) + +#define htobe64(x) _byteswap_uint64(x) +#define htole64(x) (x) +#define be64toh(x) _byteswap_uint64(x) +#define le64toh(x) (x) + +#elif defined(__linux__) #include + +#else +#error "Platform not supported" #endif diff --git a/libEpollBenchmarker/CMakeLists.txt b/libEpollBenchmarker/CMakeLists.txt new file mode 100644 index 000000000..4a624f97f --- /dev/null +++ b/libEpollBenchmarker/CMakeLists.txt @@ -0,0 +1,22 @@ +# Set the CMake minimum version +cmake_minimum_required(VERSION 3.10) + +# Project name +project(uWSLibEpollBenchmarker) +message(STATUS "Building ${PROJECT_NAME}") + +# Set C++ standard +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +# Include directories +include_directories(../src ../uSockets/src) + +# Linker flags for wrapped syscalls +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--wrap=recv,--wrap=bind,--wrap=listen,--wrap=send,--wrap=socket,--wrap=epoll_wait,--wrap=accept4,--wrap=epoll_ctl") + +# Add the executable +add_executable(${PROJECT_NAME} ../examples/HelloWorld.cpp epoll_benchmarker.cpp) + +# Link with uSockets library +target_link_libraries(${PROJECT_NAME} PRIVATE uSockets) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 000000000..5c1255f94 --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,67 @@ +cmake_minimum_required(VERSION 3.10) + +# Project name and language +project(uWebSocketsTests) +message(STATUS "Building ${PROJECT_NAME}") + +# Set the C++ standard +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +# Address sanitizer flag +set(SANITIZE_FLAGS "-fsanitize=address") + +# Define targets names with ${PROJECT_NAME} prefix +set(Query ${PROJECT_NAME}Query) +set(ChunkedEncoding ${PROJECT_NAME}ChunkedEncoding) +set(TopicTree ${PROJECT_NAME}TopicTree) +set(HttpRouter ${PROJECT_NAME}HttpRouter) +set(BloomFilter ${PROJECT_NAME}BloomFilter) +set(ExtensionsNegotiator ${PROJECT_NAME}ExtensionsNegotiator) +set(HttpParser ${PROJECT_NAME}HttpParser) + +# Define the executables and their sources +add_executable(${Query} Query.cpp) +add_executable(${ChunkedEncoding} ChunkedEncoding.cpp) +add_executable(${TopicTree} TopicTree.cpp) +add_executable(${HttpRouter} HttpRouter.cpp) +add_executable(${BloomFilter} BloomFilter.cpp) +add_executable(${ExtensionsNegotiator} ExtensionsNegotiator.cpp) +add_executable(${HttpParser} HttpParser.cpp) + +# Add the address sanitizer flags to each target +target_compile_options(${Query} PRIVATE ${SANITIZE_FLAGS}) +target_link_options(${Query} PRIVATE ${SANITIZE_FLAGS}) + +target_compile_options(${ChunkedEncoding} PRIVATE ${SANITIZE_FLAGS}) +target_link_options(${ChunkedEncoding} PRIVATE ${SANITIZE_FLAGS}) + +target_compile_options(${TopicTree} PRIVATE ${SANITIZE_FLAGS}) +target_link_options(${TopicTree} PRIVATE ${SANITIZE_FLAGS}) + +target_compile_options(${HttpRouter} PRIVATE ${SANITIZE_FLAGS}) +target_link_options(${HttpRouter} PRIVATE ${SANITIZE_FLAGS}) + +target_compile_options(${BloomFilter} PRIVATE ${SANITIZE_FLAGS}) +target_link_options(${BloomFilter} PRIVATE ${SANITIZE_FLAGS}) + +target_compile_options(${ExtensionsNegotiator} PRIVATE ${SANITIZE_FLAGS}) +target_link_options(${ExtensionsNegotiator} PRIVATE ${SANITIZE_FLAGS}) + +target_compile_options(${HttpParser} PRIVATE ${SANITIZE_FLAGS}) +target_link_options(${HttpParser} PRIVATE ${SANITIZE_FLAGS}) + +# Performance target +add_custom_target(${PROJECT_NAME}performance + COMMAND ${CMAKE_COMMAND} -E env CXXFLAGS=-O3 ${CMAKE_COMMAND} --build . --target HttpRouter + COMMAND ./HttpRouter +) + +# Smoke test target +add_custom_target(${PROJECT_NAME}smoke + COMMAND ../Crc32 & + COMMAND ${CMAKE_COMMAND} -E sleep 1 + COMMAND ~/.deno/bin/deno run --allow-net smoke.mjs + COMMAND node smoke.mjs + COMMAND pkill Crc32 +) diff --git a/uSockets b/uSockets index 4748631b0..e08b7569f 160000 --- a/uSockets +++ b/uSockets @@ -1 +1 @@ -Subproject commit 4748631b066c2a0e4fd01a6f78937d709910e17c +Subproject commit e08b7569f93c2993da4abf488d94badd7fcdd403