1 /*========================================================================= 2 * 3 * Copyright Insight Software Consortium 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0.txt 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 *=========================================================================*/ 18 #ifndef itkThreadSupport_h 19 #define itkThreadSupport_h 20 21 #include <cstdlib> 22 23 // This implementation uses a routine called SignalObjectAndWait() 24 // which is only defined on WinNT 4.0 or greater systems. We need to 25 // define this symbol in order to get the prototype for the 26 // routine. This needs to be done before we load any system headers. 27 #ifdef ITK_USE_WIN32_THREADS 28 #ifndef _WIN32_WINNT 29 #define _WIN32_WINNT 0x0501 //TBB 4.4 requires WinXP (0x0501 or greater) 30 #endif 31 #endif 32 33 #if defined(ITK_USE_PTHREADS) 34 #include <pthread.h> 35 #elif defined(ITK_USE_WIN32_THREADS) 36 #include "itkWindows.h" 37 #include <winbase.h> 38 #endif 39 #include "itkConfigure.h" 40 41 42 namespace itk 43 { 44 /** Platform specific type alias for simple types 45 */ 46 #if defined(ITK_USE_PTHREADS) 47 constexpr std::size_t ITK_MAX_THREADS = ITK_DEFAULT_MAX_THREADS; 48 using MutexType = pthread_mutex_t; 49 using FastMutexType = pthread_mutex_t; 50 using ThreadFunctionType = void *(*)(void *); 51 using ThreadProcessIdType = pthread_t; 52 constexpr ThreadProcessIdType ITK_DEFAULT_THREAD_ID = 0; 53 using ITK_THREAD_RETURN_TYPE = void *; 54 constexpr ITK_THREAD_RETURN_TYPE ITK_THREAD_RETURN_DEFAULT_VALUE = NULL; /* This is from a c library, and always needs to be NULL, not nullptr */ 55 using itk::ITK_THREAD_RETURN_DEFAULT_VALUE; //We need this out of the itk namespace for #define to work below 56 using ITK_THREAD_RETURN_FUNCTION_CALL_CONVENTION = itk::ITK_THREAD_RETURN_TYPE; 57 #elif defined(ITK_USE_WIN32_THREADS) 58 59 constexpr std::size_t ITK_MAX_THREADS = ITK_DEFAULT_MAX_THREADS; 60 using MutexType = HANDLE; 61 using FastMutexType = CRITICAL_SECTION; 62 typedef unsigned(__stdcall * ThreadFunctionType)(void *); 63 using ThreadProcessIdType = HANDLE; 64 static const ThreadProcessIdType ITK_DEFAULT_THREAD_ID = INVALID_HANDLE_VALUE; 65 using ITK_THREAD_RETURN_TYPE = unsigned; 66 constexpr ITK_THREAD_RETURN_TYPE ITK_THREAD_RETURN_DEFAULT_VALUE = 0; 67 // WINAPI expands to __stdcall which specifies a function call convention and has little no meaning on variable declarations 68 #define ITK_THREAD_RETURN_FUNCTION_CALL_CONVENTION itk::ITK_THREAD_RETURN_TYPE __stdcall 69 #else 70 71 constexpr std::size_t ITK_MAX_THREADS = 1; 72 using MutexType = int; 73 using FastMutexType = int; 74 typedef void ( *ThreadFunctionType )(void *); 75 using ThreadProcessIdType = int; 76 constexpr ThreadProcessIdType ITK_DEFAULT_THREAD_ID = 0; 77 using ITK_THREAD_RETURN_TYPE = void; 78 #define ITK_THREAD_RETURN_DEFAULT_VALUE 79 using ITK_THREAD_RETURN_FUNCTION_CALL_CONVENTION = itk::ITK_THREAD_RETURN_TYPE; 80 #endif 81 82 83 /** Platform specific Conditional Variable type alias 84 */ 85 #if defined(ITK_USE_PTHREADS) 86 typedef struct { 87 pthread_cond_t m_ConditionVariable; 88 } ConditionVariableType; 89 #elif defined(ITK_USE_WIN32_THREADS) 90 typedef struct { 91 int m_NumberOfWaiters; // number of waiting threads 92 CRITICAL_SECTION m_NumberOfWaitersLock; // Serialize access to 93 // m_NumberOfWaiters 94 95 HANDLE m_Semaphore; // Semaphore to queue threads 96 HANDLE m_WaitersAreDone; // Auto-reset event used by the 97 // broadcast/signal thread to 98 // wait for all the waiting 99 // threads to wake up and 100 // release the semaphore 101 102 int m_WasBroadcast; // Used as boolean. Keeps track of whether 103 // we were broadcasting or signaling 104 } ConditionVariableType; 105 #else 106 using ConditionVariableType = struct { }; 107 #endif 108 109 } 110 111 // Compile-time conditional code for different threading models 112 // require that some items are #defines (always global scope) or 113 // can sometimes be rigorously typed. When rigorously typed, 114 // we need to re-exposed to the global namespace to keep the 115 // use of these items consistent. 116 #if defined(ITK_USE_PTHREADS) 117 using itk::ITK_THREAD_RETURN_FUNCTION_CALL_CONVENTION; 118 using itk::ITK_THREAD_RETURN_DEFAULT_VALUE; //We need this out of the itk namespace for #define to work below 119 #elif defined(ITK_USE_WIN32_THREADS) 120 using itk::ITK_THREAD_RETURN_DEFAULT_VALUE; //We need this out of the itk namespace for #define to work below 121 #else 122 using itk::ITK_THREAD_RETURN_FUNCTION_CALL_CONVENTION; 123 #endif 124 125 // For backwards compatiblity 126 #if ! defined ( ITK_FUTURE_LEGACY_REMOVE ) 127 using itk::ITK_MAX_THREADS; 128 using itk::ITK_DEFAULT_THREAD_ID; 129 #endif 130 131 #endif 132