| # Licensed to the Apache Software Foundation (ASF) under one |
| # or more contributor license agreements. See the NOTICE file |
| # distributed with this work for additional information |
| # regarding copyright ownership. The ASF licenses this file |
| # to you under the Apache License, Version 2.0 (the |
| # "License"); you may not use this file except in compliance |
| # with the License. You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, |
| # software distributed under the License is distributed on an |
| # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| # KIND, either express or implied. See the License for the |
| # specific language governing permissions and limitations |
| # under the License. |
| |
| include(CheckIncludeFileCXX) |
| include(CheckCXXSourceCompiles) |
| |
| # Find a threading library we can use. |
| set(FOUND_THREADS FALSE) |
| |
| if(NOT FOUND_THREADS) |
| CHECK_CXX_SOURCE_COMPILES(" |
| #include <thread> |
| #include <mutex> |
| #include <condition_variable> |
| |
| int main() { |
| std::thread t; |
| |
| std::mutex m; |
| std::recursive_mutex rm; |
| |
| std::condition_variable_any cv; |
| |
| std::lock_guard<std::mutex> lock_m(m); |
| std::lock_guard<std::recursive_mutex> lock_rm(rm); |
| |
| return 0; |
| } |
| " QUICKSTEP_HAVE_CPP11_THREADS) |
| |
| if (QUICKSTEP_HAVE_CPP11_THREADS) |
| CHECK_CXX_SOURCE_COMPILES(" |
| #include <shared_mutex> |
| |
| int main() { |
| std::shared_mutex m; |
| |
| m.lock(); |
| m.unlock(); |
| |
| m.lock_shared(); |
| m.unlock_shared(); |
| |
| return 0; |
| } |
| " QUICKSTEP_HAVE_CPP17_SHARED_MUTEX) |
| |
| if (NOT QUICKSTEP_HAVE_CPP17_SHARED_MUTEX) |
| CHECK_CXX_SOURCE_COMPILES(" |
| #include <shared_mutex> |
| |
| int main() { |
| std::shared_timed_mutex m; |
| |
| m.lock(); |
| m.unlock(); |
| |
| m.lock_shared(); |
| m.unlock_shared(); |
| |
| return 0; |
| } |
| " QUICKSTEP_HAVE_CPP14_SHARED_TIMED_MUTEX) |
| endif() |
| |
| message("Using threading implementation: cpp11") |
| set(FOUND_THREADS TRUE) |
| endif() |
| endif() |
| |
| if(NOT FOUND_THREADS) |
| if(CMAKE_HAVE_PTHREAD_H) |
| message("Using threading implementation: posix") |
| set(QUICKSTEP_HAVE_POSIX_THREADS TRUE) |
| set(FOUND_THREADS TRUE) |
| endif() |
| endif() |
| |
| if(NOT FOUND_THREADS) |
| CHECK_CXX_SOURCE_COMPILES(" |
| #define WIN32_LEAN_AND_MEAN |
| #include <windows.h> |
| |
| int main() { |
| CRITICAL_SECTION cs; |
| InitializeCriticalSection(&cs); |
| EnterCriticalSection(&cs); |
| LeaveCriticalSection(&cs); |
| DeleteCriticalSection(&cs); |
| return 0; |
| } |
| " QUICKSTEP_HAVE_WINDOWS_THREADS) |
| if (QUICKSTEP_HAVE_WINDOWS_THREADS) |
| message("Using threading implementation: windows") |
| set(FOUND_THREADS TRUE) |
| endif() |
| endif() |
| |
| if(NOT FOUND_THREADS) |
| message(FATAL_ERROR "No viable threading library found.") |
| endif() |
| |
| |
| # Try to find some yield function we can use. |
| set(FOUND_YIELD FALSE) |
| |
| if (NOT FOUND_YIELD) |
| CHECK_CXX_SOURCE_COMPILES(" |
| #include <thread> |
| |
| int main() { |
| std::this_thread::yield(); |
| return 0; |
| } |
| " QUICKSTEP_HAVE_CPP11_YIELD) |
| if (QUICKSTEP_HAVE_CPP11_YIELD) |
| set(FOUND_YIELD TRUE) |
| endif() |
| endif() |
| |
| if (NOT FOUND_YIELD) |
| CHECK_CXX_SOURCE_COMPILES(" |
| #include <sched.h> |
| |
| int main() { |
| sched_yield(); |
| return 0; |
| } |
| " QUICKSTEP_HAVE_SCHED_YIELD) |
| if (QUICKSTEP_HAVE_SCHED_YIELD) |
| set(FOUND_YIELD TRUE) |
| endif() |
| endif() |
| |
| if (NOT FOUND_YIELD) |
| CHECK_CXX_SOURCE_COMPILES(" |
| #include <pthread.h> |
| |
| int main() { |
| pthread_yield(); |
| return 0; |
| } |
| " QUICKSTEP_HAVE_PTHREAD_YIELD) |
| if (QUICKSTEP_HAVE_PTHREAD_YIELD) |
| set(FOUND_YIELD TRUE) |
| endif() |
| endif() |
| |
| if (NOT FOUND_YIELD) |
| CHECK_CXX_SOURCE_COMPILES(" |
| #define WIN32_LEAN_AND_MEAN |
| #include <windows.h> |
| |
| int main() { |
| SwitchToThread(); |
| return 0; |
| } |
| " QUICKSTEP_HAVE_WIN_SWITCHTOTHREAD) |
| if (QUICKSTEP_HAVE_WIN_SWITCHTOTHREAD) |
| set(FOUND_YIELD TRUE) |
| endif() |
| endif() |
| |
| if(NOT FOUND_YIELD) |
| message(WARNING "No yield function found. ThreadUtil::Yield() will be a no-op.") |
| endif() |
| |
| # Try to find a thread-affinitization function that we can use. First, try the |
| # Linux version of pthread_setaffinity_np(). |
| CHECK_CXX_SOURCE_COMPILES(" |
| #ifndef _GNU_SOURCE |
| #define _GNU_SOURCE 1 |
| #endif |
| #include <pthread.h> |
| #include <sched.h> |
| |
| int main() { |
| cpu_set_t cpuset; |
| CPU_ZERO(&cpuset); |
| CPU_SET(0, &cpuset); |
| if (pthread_setaffinity_np(pthread_self(), sizeof(cpuset), &cpuset) != 0) { |
| return 1; |
| } |
| return 0; |
| } |
| " QUICKSTEP_HAVE_PTHREAD_SETAFFINITY_NP_LINUX) |
| |
| # Next, try the FreeBSD version of pthread_setaffinity_np(). It is almost |
| # identical to the Linux version, except that it is in the special header |
| # pthread_np.h, and the CPU set type is called cpuset_t instead of cpu_set_t. |
| if (NOT QUICKSTEP_HAVE_PTHREAD_SETAFFINITY_NP_LINUX) |
| CHECK_CXX_SOURCE_COMPILES(" |
| #ifndef _BSD_SOURCE |
| #define _BSD_SOURCE 1 |
| #endif |
| #include <pthread.h> |
| #include <pthread_np.h> |
| #include <sched.h> |
| |
| int main() { |
| cpuset_t cpuset; |
| CPU_ZERO(&cpuset); |
| CPU_SET(0, &cpuset); |
| if (pthread_setaffinity_np(pthread_self(), sizeof(cpuset), &cpuset) != 0) { |
| return 1; |
| } |
| return 0; |
| } |
| " QUICKSTEP_HAVE_PTHREAD_SETAFFINITY_NP_FREEBSD) |
| endif() |
| |
| # Finally, try the NetBSD version of pthread_setaffinity_np(). Unlike Linux or |
| # FreeBSD, NetBSD's version of cpuset_t is dynamically allocated/freed on the |
| # heap by some special functions in sched.h. |
| if (NOT (QUICKSTEP_HAVE_PTHREAD_SETAFFINITY_NP_LINUX OR QUICKSTEP_HAVE_PTHREAD_SETAFFINITY_NP_FREEBSD)) |
| CHECK_CXX_SOURCE_COMPILES(" |
| #ifndef _BSD_SOURCE |
| #define _BSD_SOURCE 1 |
| #endif |
| #include <pthread.h> |
| #include <sched.h> |
| |
| int main() { |
| cpuset_t *cset = cpuset_create(); |
| if (cpuset_set(0, cset) != 0) { |
| return 1; |
| } |
| if (pthread_setaffinity_np(pthread_self(), cpuset_size(cset), cset) != 0) { |
| return 1; |
| } |
| cpuset_destroy(cset); |
| return 0; |
| } |
| " QUICKSTEP_HAVE_PTHREAD_SETAFFINITY_NP_NETBSD) |
| endif() |
| |
| if (NOT (QUICKSTEP_HAVE_PTHREAD_SETAFFINITY_NP_LINUX |
| OR QUICKSTEP_HAVE_PTHREAD_SETAFFINITY_NP_FREEBSD |
| OR QUICKSTEP_HAVE_PTHREAD_SETAFFINITY_NP_NETBSD)) |
| message(WARNING "Thread pinning operation will be a no-op.") |
| endif() |
| |
| configure_file ( |
| "${CMAKE_CURRENT_SOURCE_DIR}/ThreadingConfig.h.in" |
| "${CMAKE_CURRENT_BINARY_DIR}/ThreadingConfig.h" |
| ) |
| |
| # Declare micro-libs: |
| if (QUICKSTEP_HAVE_CPP11_THREADS) |
| add_library(quickstep_threading_ConditionVariable |
| ConditionVariable.cpp |
| ConditionVariable.hpp |
| cpp11/ConditionVariable.hpp) |
| add_library(quickstep_threading_Mutex |
| Mutex.cpp |
| Mutex.hpp |
| cpp11/Mutex.hpp) |
| if (QUICKSTEP_HAVE_CPP14_SHARED_MUTEX) |
| add_library(quickstep_threading_SharedMutex |
| ../empty_src.cpp |
| SharedMutex.hpp |
| cpp11/cpp14/SharedMutex.hpp) |
| else() |
| add_library(quickstep_threading_SharedMutex |
| ../empty_src.cpp |
| SharedMutex.hpp |
| cpp11/SharedMutex.hpp) |
| endif() |
| add_library(quickstep_threading_Thread |
| Thread.cpp |
| Thread.hpp |
| cpp11/Thread.hpp) |
| elseif (QUICKSTEP_HAVE_POSIX_THREADS) |
| add_library(quickstep_threading_ConditionVariable |
| ConditionVariable.cpp |
| ConditionVariable.hpp |
| posix/ConditionVariable.hpp) |
| add_library(quickstep_threading_Mutex |
| Mutex.cpp |
| Mutex.hpp |
| posix/Mutex.hpp) |
| add_library(quickstep_threading_SharedMutex |
| ../empty_src.cpp |
| SharedMutex.hpp |
| posix/SharedMutex.hpp) |
| add_library(quickstep_threading_Thread |
| Thread.cpp |
| Thread.hpp |
| posix/Thread.hpp) |
| elseif (QUICKSTEP_HAVE_WINDOWS_THREADS) |
| add_library(quickstep_threading_ConditionVariable |
| ConditionVariable.cpp |
| ConditionVariable.hpp |
| windows/ConditionVariable.hpp) |
| add_library(quickstep_threading_Mutex |
| Mutex.cpp |
| Mutex.hpp |
| windows/Mutex.hpp) |
| add_library(quickstep_threading_SharedMutex |
| ../empty_src.cpp |
| SharedMutex.hpp |
| windows/SharedMutex.hpp) |
| add_library(quickstep_threading_Thread |
| Thread.cpp |
| Thread.hpp |
| windows/Thread.hpp) |
| endif() |
| |
| add_library(quickstep_threading_SpinMutex ../empty_src.cpp SpinMutex.hpp) |
| add_library(quickstep_threading_SpinSharedMutex ../empty_src.cpp SpinSharedMutex.hpp) |
| add_library(quickstep_threading_ThreadIDBasedMap ../empty_src.cpp ThreadIDBasedMap.hpp) |
| add_library(quickstep_threading_ThreadUtil ../empty_src.cpp ThreadUtil.hpp) |
| |
| # Link dependencies: |
| target_link_libraries(quickstep_threading_ConditionVariable |
| glog |
| quickstep_utility_Macros) |
| target_link_libraries(quickstep_threading_Mutex |
| glog |
| quickstep_threading_ConditionVariable |
| quickstep_utility_Macros |
| quickstep_utility_PtrVector) |
| if (QUICKSTEP_HAVE_CPP11_THREADS AND NOT QUICKSTEP_HAVE_CPP14_SHARED_MUTEX) |
| target_link_libraries(quickstep_threading_SharedMutex |
| glog |
| quickstep_threading_ConditionVariable |
| quickstep_threading_Mutex |
| quickstep_utility_Macros) |
| else() |
| target_link_libraries(quickstep_threading_SharedMutex |
| quickstep_threading_Mutex |
| quickstep_utility_Macros) |
| endif() |
| target_link_libraries(quickstep_threading_SpinMutex |
| quickstep_threading_Mutex |
| quickstep_utility_Macros) |
| target_link_libraries(quickstep_threading_SpinSharedMutex |
| quickstep_threading_Mutex |
| quickstep_threading_SharedMutex |
| quickstep_threading_ThreadUtil |
| quickstep_utility_Macros) |
| target_link_libraries(quickstep_threading_Thread |
| quickstep_utility_Macros) |
| target_link_libraries(quickstep_threading_ThreadIDBasedMap |
| glog |
| quickstep_storage_StorageConstants |
| quickstep_threading_Mutex |
| quickstep_threading_SharedMutex |
| quickstep_threading_SpinSharedMutex |
| quickstep_utility_Macros) |
| target_link_libraries(quickstep_threading_ThreadUtil |
| quickstep_utility_Macros) |
| |
| # Module all-in-one library: |
| add_library(quickstep_threading ../empty_src.cpp ThreadingModule.hpp) |
| target_link_libraries(quickstep_threading |
| quickstep_threading_ConditionVariable |
| quickstep_threading_Mutex |
| quickstep_threading_SharedMutex |
| quickstep_threading_SpinMutex |
| quickstep_threading_SpinSharedMutex |
| quickstep_threading_Thread |
| quickstep_threading_ThreadIDBasedMap |
| quickstep_threading_ThreadUtil) |
| |
| # Tests: |
| add_executable(Mutex_unittest "${CMAKE_CURRENT_SOURCE_DIR}/tests/Mutex_unittest.cpp") |
| target_link_libraries(Mutex_unittest |
| gtest |
| gtest_main |
| quickstep_threading_Mutex |
| quickstep_threading_SpinMutex |
| quickstep_threading_Thread |
| quickstep_utility_Macros |
| ${CMAKE_THREAD_LIBS_INIT}) |
| add_test(Mutex_unittest Mutex_unittest) |
| |
| add_executable(SharedMutex_unittest "${CMAKE_CURRENT_SOURCE_DIR}/tests/SharedMutex_unittest.cpp") |
| target_link_libraries(SharedMutex_unittest |
| gtest |
| gtest_main |
| quickstep_threading_Mutex |
| quickstep_threading_SharedMutex |
| quickstep_threading_SpinSharedMutex |
| quickstep_threading_Thread |
| quickstep_utility_Macros |
| ${CMAKE_THREAD_LIBS_INIT}) |
| add_test(SharedMutex_unittest SharedMutex_unittest) |