| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- # 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"
- )
|