You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kamailio/cmake/lock_methods.cmake

162 lines
5.5 KiB

# Locking method selection
# Default Priority list (auto): FUTEX > FAST_LOCK > PTHREAD_MUTEX > POSIX_SEM > SYSV_SEM
set(DEFAULT_LOCK_PRIORITY FUTEX FAST_LOCK PTHREAD_MUTEX POSIX_SEM SYSV_SEM)
# Architecture-specific priorities (can be extended)
# Example: On aarch64, prefer PTHREAD_MUTEX > FAST_LOCK > FUTEX
set(aarch64_LOCK_PRIORITY PTHREAD_MUTEX FAST_LOCK FUTEX POSIX_SEM SYSV_SEM)
# Add more as needed
# set(x86_64_LOCK_PRIORITY FUTEX FAST_LOCK PTHREAD_MUTEX ...)
# Public cache variable (user may force one); AUTO means detect
set(locking_methods "AUTO" "FAST_LOCK" "FUTEX" "PTHREAD_MUTEX" "POSIX_SEM" "SYSV_SEM")
set(LOCK_METHOD
"AUTO"
CACHE
STRING
"Locking method to use (AUTO, or one of: FUTEX FAST_LOCK PTHREAD_MUTEX POSIX_SEM SYSV_SEM)"
)
# List of locking methods in option
set_property(CACHE LOCK_METHOD PROPERTY STRINGS ${locking_methods})
mark_as_advanced(LOCK_METHOD)
# Determine the priority list for the current architecture
if(DEFINED ${TARGET_ARCH}_LOCK_PRIORITY)
set(_LOCK_PRIORITY ${${TARGET_ARCH}_LOCK_PRIORITY})
else()
set(_LOCK_PRIORITY ${DEFAULT_LOCK_PRIORITY})
endif()
message(DEBUG "Lock priority for architecture ${TARGET_ARCH}: ${_LOCK_PRIORITY}")
# Set default locking method if not set
if(NOT LOCK_METHOD)
message(STATUS "No locking method specified, using default: AUTO")
set(LOCK_METHOD "AUTO")
endif()
# Validate the selected locking method
if(NOT LOCK_METHOD IN_LIST locking_methods)
message(
FATAL_ERROR
"Invalid locking method selected: ${LOCK_METHOD}. Methods available are: ${locking_methods}"
)
endif()
# Availability checks
# FUTEX: linux/futex.h
find_path(FUTEX_HEADER_DIR linux/futex.h)
if(FUTEX_HEADER_DIR)
set(_HAVE_FUTEX TRUE)
# This conditional checks if the TARGET_ARCH does not match any of the specified supported architectures.
# The supported architectures include see atomic_native.h and atomic_(arhitecture).h files:
# - Alpha: alpha: atomic_alpha.h
# - ARM variants: arm6, and arm7: atomic_arm.h
# - MIPS variants: mips, mips2, and mips64: atomic_mips.h
# - PowerPC variants: ppc and ppc64: atomic_ppc.h
# - SPARC variants: sparc and sparc64: atomic_sparc.h and atomic_sparc64.h
# - x86 variants: i386 and x86_64: atomic_x86.h
if(NOT
"${TARGET_ARCH}"
MATCHES
"^(i386|x86_64)$|^(mips|mips2|mips64)$|^(ppc|ppc64)$|^(sparc|sparc64)$|^(arm6|arm7|aarch64)$|^alpha$"
)
set(_HAVE_FUTEX FALSE)
endif()
else()
set(_HAVE_FUTEX FALSE)
endif()
# PTHREAD: pthread.h (assume present on typical systems)
find_path(PTHREAD_HEADER_DIR pthread.h)
if(PTHREAD_HEADER_DIR)
set(_HAVE_PTHREAD_MUTEX TRUE)
else()
set(_HAVE_PTHREAD_MUTEX FALSE)
endif()
# POSIX SEM: semaphore.h
find_path(SEM_HEADER_DIR semaphore.h)
if(SEM_HEADER_DIR)
set(_HAVE_POSIX_SEM TRUE)
else()
set(_HAVE_POSIX_SEM FALSE)
endif()
# SYSV SEM: sys/sem.h
find_path(SYSV_SEM_HEADER_DIR sys/sem.h)
if(SYSV_SEM_HEADER_DIR)
set(_HAVE_SYSV_SEM TRUE)
else()
set(_HAVE_SYSV_SEM FALSE)
endif()
# check fast-lock arch support
if("${TARGET_ARCH}" MATCHES
"i386$|x86_64$|aarch64$|arm$|arm6$|arm7$|ppc$|ppc64$|sparc64$|sparc$|alpha$|mips2$|mips64$"
)
set(_HAVE_FAST_LOCK TRUE)
elseif("${TARGET_ARCH}" MATCHES "mips$")
# explicitly unsupported (old code added extra defs)
set(_HAVE_FAST_LOCK FALSE)
else()
set(_HAVE_FAST_LOCK FALSE)
endif()
message(
STATUS
"Locking Methods for this platform: FUTEX=${_HAVE_FUTEX} FAST_LOCK=${_HAVE_FAST_LOCK} PTHREAD_MUTEX=${_HAVE_PTHREAD_MUTEX} POSIX_SEM=${_HAVE_POSIX_SEM} SYSV_SEM=${_HAVE_SYSV_SEM}"
)
# Final locking method selection logic
set(_SELECTED_LOCK_METHOD "")
if("${LOCK_METHOD}" STREQUAL "AUTO")
# Iterate through the priority list for the current arch
foreach(method IN LISTS _LOCK_PRIORITY)
if(_HAVE_${method})
set(_SELECTED_LOCK_METHOD "${method}")
break()
endif()
endforeach()
if(_SELECTED_LOCK_METHOD STREQUAL "")
message(FATAL_ERROR "No supported locking method found for this platform.")
endif()
else()
set(_SELECTED_LOCK_METHOD "${LOCK_METHOD}")
endif()
message(STATUS "Selected locking method: ${_SELECTED_LOCK_METHOD}")
# Set compile definitions based on the selected method
if("${_SELECTED_LOCK_METHOD}" STREQUAL "FUTEX")
target_compile_definitions(common INTERFACE USE_FUTEX)
elseif("${_SELECTED_LOCK_METHOD}" STREQUAL "FAST_LOCK")
target_compile_definitions(common INTERFACE FAST_LOCK ADAPTIVE_WAIT ADAPTIVE_WAIT_LOOPS=1024)
if("${TARGET_ARCH}" MATCHES "mips$")
# Add special definitions for mips + FAST_LOCK
target_compile_definitions(common INTERFACE MIPS_HAS_LLSC) # likely
target_compile_definitions(common INTERFACE NOSMP) # very likely
elseif("${TARGET_ARCH}" MATCHES "arm$|aarch64$")
target_compile_definitions(common INTERFACE NOSMP) # memory barriers not implemented for arm
endif()
elseif("${_SELECTED_LOCK_METHOD}" STREQUAL "PTHREAD_MUTEX")
target_compile_definitions(common INTERFACE USE_PTHREAD_MUTEX)
target_link_libraries(common INTERFACE pthread)
elseif("${_SELECTED_LOCK_METHOD}" STREQUAL "POSIX_SEM")
target_compile_definitions(common INTERFACE USE_POSIX_SEM)
target_link_libraries(common INTERFACE pthread)
elseif("${_SELECTED_LOCK_METHOD}" STREQUAL "SYSV_SEM")
target_compile_definitions(common INTERFACE USE_SYSV_SEM)
else()
message(FATAL_ERROR "Unknown locking method: ${_SELECTED_LOCK_METHOD}")
endif()
# Cache the final locking method for use in other parts of the build
# This is an internal cache variable, not meant for user modification
set(LOCK_METHOD_FINAL
"${_SELECTED_LOCK_METHOD}"
CACHE INTERNAL "Final locking method selected"
)