Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
dto-test*
libdto.so*
build*/
tests/baselines*/
208 changes: 208 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
cmake_minimum_required(VERSION 3.5...3.31)
project(DTO VERSION 1.0 LANGUAGES C)

# Default to RelWithDebInfo when no build type is specified.
# (Skip for multi-config generators, which ignore CMAKE_BUILD_TYPE.)
get_property(_is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(NOT _is_multi_config AND NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING
"Choose the type of build" FORCE)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
Debug Release RelWithDebInfo MinSizeRel)
message(STATUS "No build type specified, defaulting to RelWithDebInfo")
endif()

include(GNUInstallDirs)
set(CMAKE_INSTALL_LIBDIR lib)

# Options to enable/disable library support (on by default)
option(DTO_ACCEL_CONFIG_SUPPORT "Enable accel-config for automatic DSA discovery (requires libaccel-config)" ON)
option(DTO_NUMA_SUPPORT "Enable NUMA awareness support (requires libnuma)" ON)

# Options to statically link dependencies into libdto.so
option(DTO_STATIC_ACCEL_CONFIG "Statically link accel-config into libdto.so" OFF)
option(DTO_STATIC_NUMA "Statically link numa into libdto.so (requires PIC-compiled libnuma.a)" OFF)

# Build the shared library
add_library(dto SHARED dto.c)
add_library(DTO::dto ALIAS dto)
target_include_directories(dto
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)

# set gnu source everywhere
add_compile_definitions(_GNU_SOURCE)

# Add the -DDTO_STATS_SUPPORT preprocessor definition
target_compile_definitions(dto PRIVATE DTO_STATS_SUPPORT)

# Link libraries
set(DTO_STATIC_LIBS "")
set(DTO_DYNAMIC_LIBS dl)

# Handle accel-config support
if(DTO_ACCEL_CONFIG_SUPPORT)
target_compile_definitions(dto PRIVATE DTO_ACCEL_CONFIG_SUPPORT)
message(STATUS "accel-config support: enabled")

if(DTO_STATIC_ACCEL_CONFIG)
find_library(ACCEL_CONFIG_STATIC NAMES libaccel-config.a PATHS /usr/lib /usr/local/lib /usr/lib/x86_64-linux-gnu)
if(NOT ACCEL_CONFIG_STATIC)
message(FATAL_ERROR "libaccel-config.a not found. Install static accel-config or disable DTO_STATIC_ACCEL_CONFIG.")
endif()
message(STATUS "Statically linking accel-config: ${ACCEL_CONFIG_STATIC}")
list(APPEND DTO_STATIC_LIBS ${ACCEL_CONFIG_STATIC})
else()
list(APPEND DTO_DYNAMIC_LIBS accel-config)
endif()
else()
message(STATUS "accel-config support: disabled (DTO_WQ_LIST env var required at runtime)")
endif()

# Handle numa support
if(DTO_NUMA_SUPPORT)
target_compile_definitions(dto PRIVATE DTO_NUMA_SUPPORT)
message(STATUS "NUMA support: enabled")

if(DTO_STATIC_NUMA)
find_library(NUMA_STATIC NAMES libnuma.a PATHS /usr/lib /usr/local/lib /usr/lib/x86_64-linux-gnu)
if(NOT NUMA_STATIC)
message(FATAL_ERROR "libnuma.a not found. Install static numa or disable DTO_STATIC_NUMA.")
endif()
message(STATUS "Statically linking numa: ${NUMA_STATIC}")
message(STATUS " (Note: libnuma.a must be compiled with -fPIC)")
list(APPEND DTO_STATIC_LIBS ${NUMA_STATIC})
else()
list(APPEND DTO_DYNAMIC_LIBS numa)
endif()
else()
message(STATUS "NUMA support: disabled")
endif()

# Link everything together
if(DTO_STATIC_LIBS)
target_link_libraries(dto
-Wl,--whole-archive
${DTO_STATIC_LIBS}
-Wl,--no-whole-archive
${DTO_DYNAMIC_LIBS}
)
else()
target_link_libraries(dto ${DTO_DYNAMIC_LIBS})
endif()

include(CheckCCompilerFlag)
check_c_compiler_flag("-mwaitpkg" HAS_WAITPKG)
if (HAS_WAITPKG)
target_compile_options(dto PRIVATE -mwaitpkg -march=native)
endif()

# Build dto-test and dto-test-wodto
add_executable(dto-test dto-test.c)
target_link_libraries(dto-test PRIVATE DTO::dto pthread)

add_executable(dto-test-wodto dto-test.c)
target_link_libraries(dto-test-wodto PRIVATE pthread)

# ---- Test Suite ----
option(DTO_BUILD_TESTS "Build the DTO test suite" ON)

if(DTO_BUILD_TESTS)
enable_testing()

# Functional correctness tests (safe to run in CI without DSA hardware)
add_executable(dto-test-functional tests/test_functional.c)
target_link_libraries(dto-test-functional PRIVATE DTO::dto pthread)

add_test(NAME functional COMMAND dto-test-functional)
set_tests_properties(functional PROPERTIES
LABELS "functional"
TIMEOUT 120
)

# Build current dto.c as object file with renamed symbols (cur_memcpy, etc.)
set(PERF_BASELINE_DIR "${CMAKE_BINARY_DIR}/perf_baseline")

add_custom_command(
OUTPUT ${CMAKE_BINARY_DIR}/dto_current.o
COMMAND ${CMAKE_C_COMPILER} -c -O3 -DNDEBUG -march=native -mwaitpkg -fPIC
-D_GNU_SOURCE -DDTO_STATS_SUPPORT
${CMAKE_SOURCE_DIR}/dto.c
-o ${CMAKE_BINARY_DIR}/dto_current_raw.o
COMMAND objcopy --redefine-sym memcpy=cur_memcpy
--redefine-sym memset=cur_memset
--redefine-sym memcmp=cur_memcmp
--redefine-sym memmove=cur_memmove
${CMAKE_BINARY_DIR}/dto_current_raw.o
${CMAKE_BINARY_DIR}/dto_current.o
DEPENDS ${CMAKE_SOURCE_DIR}/dto.c
COMMENT "Building dto_current.o with renamed symbols"
)

# Build baseline dto.o from baseline branch (cached by SHA)
add_custom_command(
OUTPUT ${PERF_BASELINE_DIR}/dto_baseline.o
COMMAND bash ${CMAKE_SOURCE_DIR}/tests/build_baseline.sh
${CMAKE_SOURCE_DIR} ${PERF_BASELINE_DIR}
DEPENDS ${CMAKE_SOURCE_DIR}/tests/build_baseline.sh
COMMENT "Building dto_baseline.o from baseline branch"
)

add_executable(dto-test-perf-combined
tests/test_perf_combined.c
${CMAKE_BINARY_DIR}/dto_current.o
${PERF_BASELINE_DIR}/dto_baseline.o
)
target_link_libraries(dto-test-perf-combined PRIVATE m dl accel-config numa)

# Common env vars for perf tests
# Pin frequency to 2000 MHz by default; override with -DPERF_FREQ_MHZ=...
if(NOT DEFINED PERF_FREQ_MHZ)
set(PERF_FREQ_MHZ 2000)
endif()

set(PERF_COMMON_ENV
"RESULTS_DIR=${CMAKE_BINARY_DIR}/perf_results"
"PERF_FREQ_MHZ=${PERF_FREQ_MHZ}"
)

# --- Combined A/B test (all configs + page sizes in one run) ---
add_test(NAME perf_combined COMMAND dto-test-perf-combined)
set_tests_properties(perf_combined PROPERTIES
LABELS "perf"
TIMEOUT 2400
ENVIRONMENT "${PERF_COMMON_ENV}"
)
endif()

# Install and export the library
install(TARGETS dto
EXPORT DTOTargets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})

install(FILES dto.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})

install(EXPORT DTOTargets
FILE DTOTargets.cmake
NAMESPACE DTO::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/DTO)

include(CMakePackageConfigHelpers)
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/DTOConfigVersion.cmake"
VERSION ${PROJECT_VERSION}
COMPATIBILITY AnyNewerVersion)

configure_package_config_file(
"${CMAKE_CURRENT_SOURCE_DIR}/DTOConfig.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/DTOConfig.cmake"
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/DTO)

install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/DTOConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/DTOConfigVersion.cmake"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/DTO)

5 changes: 5 additions & 0 deletions DTOConfig.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@PACKAGE_INIT@

include("${CMAKE_CURRENT_LIST_DIR}/DTOTargets.cmake")

check_required_components(DTO)
Loading