lock_methods.cmake 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. # Locking method selection
  2. # Default Priority list (auto): FUTEX > FAST_LOCK > PTHREAD_MUTEX > POSIX_SEM > SYSV_SEM
  3. set(DEFAULT_LOCK_PRIORITY FUTEX FAST_LOCK PTHREAD_MUTEX POSIX_SEM SYSV_SEM)
  4. # Architecture-specific priorities (can be extended)
  5. # Example: On aarch64, prefer PTHREAD_MUTEX > FAST_LOCK > FUTEX
  6. set(aarch64_LOCK_PRIORITY PTHREAD_MUTEX FAST_LOCK FUTEX POSIX_SEM SYSV_SEM)
  7. # Add more as needed
  8. # set(x86_64_LOCK_PRIORITY FUTEX FAST_LOCK PTHREAD_MUTEX ...)
  9. # Public cache variable (user may force one); AUTO means detect
  10. set(locking_methods "AUTO" "FAST_LOCK" "FUTEX" "PTHREAD_MUTEX" "POSIX_SEM" "SYSV_SEM")
  11. set(LOCK_METHOD
  12. "AUTO"
  13. CACHE
  14. STRING
  15. "Locking method to use (AUTO, or one of: FUTEX FAST_LOCK PTHREAD_MUTEX POSIX_SEM SYSV_SEM)"
  16. )
  17. # List of locking methods in option
  18. set_property(CACHE LOCK_METHOD PROPERTY STRINGS ${locking_methods})
  19. mark_as_advanced(LOCK_METHOD)
  20. # Determine the priority list for the current architecture
  21. if(DEFINED ${TARGET_ARCH}_LOCK_PRIORITY)
  22. set(_LOCK_PRIORITY ${${TARGET_ARCH}_LOCK_PRIORITY})
  23. else()
  24. set(_LOCK_PRIORITY ${DEFAULT_LOCK_PRIORITY})
  25. endif()
  26. message(DEBUG "Lock priority for architecture ${TARGET_ARCH}: ${_LOCK_PRIORITY}")
  27. # Set default locking method if not set
  28. if(NOT LOCK_METHOD)
  29. message(STATUS "No locking method specified, using default: AUTO")
  30. set(LOCK_METHOD "AUTO")
  31. endif()
  32. # Validate the selected locking method
  33. if(NOT LOCK_METHOD IN_LIST locking_methods)
  34. message(
  35. FATAL_ERROR
  36. "Invalid locking method selected: ${LOCK_METHOD}. Methods available are: ${locking_methods}"
  37. )
  38. endif()
  39. # Availability checks
  40. # FUTEX: linux/futex.h
  41. find_path(FUTEX_HEADER_DIR linux/futex.h)
  42. if(FUTEX_HEADER_DIR)
  43. set(_HAVE_FUTEX TRUE)
  44. # This conditional checks if the TARGET_ARCH does not match any of the specified supported architectures.
  45. # The supported architectures include see atomic_native.h and atomic_(arhitecture).h files:
  46. # - Alpha: alpha: atomic_alpha.h
  47. # - ARM variants: arm6, and arm7: atomic_arm.h
  48. # - MIPS variants: mips, mips2, and mips64: atomic_mips.h
  49. # - PowerPC variants: ppc and ppc64: atomic_ppc.h
  50. # - SPARC variants: sparc and sparc64: atomic_sparc.h and atomic_sparc64.h
  51. # - x86 variants: i386 and x86_64: atomic_x86.h
  52. if(NOT
  53. "${TARGET_ARCH}"
  54. MATCHES
  55. "^(i386|x86_64)$|^(mips|mips2|mips64)$|^(ppc|ppc64)$|^(sparc|sparc64)$|^(arm6|arm7|aarch64)$|^alpha$"
  56. )
  57. set(_HAVE_FUTEX FALSE)
  58. endif()
  59. else()
  60. set(_HAVE_FUTEX FALSE)
  61. endif()
  62. # PTHREAD: pthread.h (assume present on typical systems)
  63. find_path(PTHREAD_HEADER_DIR pthread.h)
  64. if(PTHREAD_HEADER_DIR)
  65. set(_HAVE_PTHREAD_MUTEX TRUE)
  66. else()
  67. set(_HAVE_PTHREAD_MUTEX FALSE)
  68. endif()
  69. # POSIX SEM: semaphore.h
  70. find_path(SEM_HEADER_DIR semaphore.h)
  71. if(SEM_HEADER_DIR)
  72. set(_HAVE_POSIX_SEM TRUE)
  73. else()
  74. set(_HAVE_POSIX_SEM FALSE)
  75. endif()
  76. # SYSV SEM: sys/sem.h
  77. find_path(SYSV_SEM_HEADER_DIR sys/sem.h)
  78. if(SYSV_SEM_HEADER_DIR)
  79. set(_HAVE_SYSV_SEM TRUE)
  80. else()
  81. set(_HAVE_SYSV_SEM FALSE)
  82. endif()
  83. # check fast-lock arch support
  84. if("${TARGET_ARCH}" MATCHES
  85. "i386$|x86_64$|aarch64$|arm$|arm6$|arm7$|ppc$|ppc64$|sparc64$|sparc$|alpha$|mips2$|mips64$"
  86. )
  87. set(_HAVE_FAST_LOCK TRUE)
  88. elseif("${TARGET_ARCH}" MATCHES "mips$")
  89. # explicitly unsupported (old code added extra defs)
  90. set(_HAVE_FAST_LOCK FALSE)
  91. else()
  92. set(_HAVE_FAST_LOCK FALSE)
  93. endif()
  94. message(
  95. STATUS
  96. "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}"
  97. )
  98. # Final locking method selection logic
  99. set(_SELECTED_LOCK_METHOD "")
  100. if("${LOCK_METHOD}" STREQUAL "AUTO")
  101. # Iterate through the priority list for the current arch
  102. foreach(method IN LISTS _LOCK_PRIORITY)
  103. if(_HAVE_${method})
  104. set(_SELECTED_LOCK_METHOD "${method}")
  105. break()
  106. endif()
  107. endforeach()
  108. if(_SELECTED_LOCK_METHOD STREQUAL "")
  109. message(FATAL_ERROR "No supported locking method found for this platform.")
  110. endif()
  111. else()
  112. set(_SELECTED_LOCK_METHOD "${LOCK_METHOD}")
  113. endif()
  114. message(STATUS "Selected locking method: ${_SELECTED_LOCK_METHOD}")
  115. # Set compile definitions based on the selected method
  116. if("${_SELECTED_LOCK_METHOD}" STREQUAL "FUTEX")
  117. target_compile_definitions(common INTERFACE USE_FUTEX)
  118. elseif("${_SELECTED_LOCK_METHOD}" STREQUAL "FAST_LOCK")
  119. target_compile_definitions(common INTERFACE FAST_LOCK ADAPTIVE_WAIT ADAPTIVE_WAIT_LOOPS=1024)
  120. if("${TARGET_ARCH}" MATCHES "mips$")
  121. # Add special definitions for mips + FAST_LOCK
  122. target_compile_definitions(common INTERFACE MIPS_HAS_LLSC) # likely
  123. target_compile_definitions(common INTERFACE NOSMP) # very likely
  124. elseif("${TARGET_ARCH}" MATCHES "arm$|aarch64$")
  125. target_compile_definitions(common INTERFACE NOSMP) # memory barriers not implemented for arm
  126. endif()
  127. elseif("${_SELECTED_LOCK_METHOD}" STREQUAL "PTHREAD_MUTEX")
  128. target_compile_definitions(common INTERFACE USE_PTHREAD_MUTEX)
  129. target_link_libraries(common INTERFACE pthread)
  130. elseif("${_SELECTED_LOCK_METHOD}" STREQUAL "POSIX_SEM")
  131. target_compile_definitions(common INTERFACE USE_POSIX_SEM)
  132. target_link_libraries(common INTERFACE pthread)
  133. elseif("${_SELECTED_LOCK_METHOD}" STREQUAL "SYSV_SEM")
  134. target_compile_definitions(common INTERFACE USE_SYSV_SEM)
  135. else()
  136. message(FATAL_ERROR "Unknown locking method: ${_SELECTED_LOCK_METHOD}")
  137. endif()
  138. # Cache the final locking method for use in other parts of the build
  139. # This is an internal cache variable, not meant for user modification
  140. set(LOCK_METHOD_FINAL
  141. "${_SELECTED_LOCK_METHOD}"
  142. CACHE INTERNAL "Final locking method selected"
  143. )