X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=common%2Fos_thread.hpp;h=2c3f73250893e9beba24bc84781acedf8f1e4775;hb=93d51c3065260cdb088f33d3e6d5bdfb4707c1a9;hp=6c0b488c0152474a031a82839b0c767777714fdd;hpb=bcb5850afb381e4814d247917311494d7edd2e91;p=apitrace diff --git a/common/os_thread.hpp b/common/os_thread.hpp index 6c0b488..2c3f732 100644 --- a/common/os_thread.hpp +++ b/common/os_thread.hpp @@ -24,9 +24,9 @@ **************************************************************************/ /* - * Simple OS abstraction. + * OS native thread abstraction. * - * Mimics C++11 / boost threads. + * Mimics C++11 threads. */ #ifndef _OS_THREAD_HPP_ @@ -40,6 +40,9 @@ #endif +#define USE_WIN32_CONDITION_VARIABLES 0 + + /** * Compiler TLS. * @@ -203,16 +206,31 @@ namespace os { */ class condition_variable { - public: + private: #ifdef _WIN32 +# if USE_WIN32_CONDITION_VARIABLES + // XXX: Only supported on Vista an higher. Not yet supported by WINE. typedef CONDITION_VARIABLE native_handle_type; + native_handle_type _native_handle; +#else + // http://www.cs.wustl.edu/~schmidt/win32-cv-1.html + LONG cWaiters; + HANDLE hEvent; +#endif #else typedef pthread_cond_t native_handle_type; + native_handle_type _native_handle; #endif + public: condition_variable() { #ifdef _WIN32 +# if USE_WIN32_CONDITION_VARIABLES InitializeConditionVariable(&_native_handle); +# else + cWaiters = 0; + hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); +# endif #else pthread_cond_init(&_native_handle, NULL); #endif @@ -220,7 +238,11 @@ namespace os { ~condition_variable() { #ifdef _WIN32 +# if USE_WIN32_CONDITION_VARIABLES /* No-op */ +# else + CloseHandle(hEvent); +# endif #else pthread_cond_destroy(&_native_handle); #endif @@ -229,7 +251,13 @@ namespace os { inline void signal(void) { #ifdef _WIN32 +# if USE_WIN32_CONDITION_VARIABLES WakeConditionVariable(&_native_handle); +# else + if (cWaiters) { + SetEvent(hEvent); + } +# endif #else pthread_cond_signal(&_native_handle); #endif @@ -239,119 +267,60 @@ namespace os { wait(unique_lock & lock) { mutex::native_handle_type & mutex_native_handle = lock.mutex()->native_handle(); #ifdef _WIN32 - /* FIXME */ +# if USE_WIN32_CONDITION_VARIABLES SleepConditionVariableCS(&_native_handle, &mutex_native_handle, INFINITE); +# else + InterlockedIncrement(&cWaiters); + LeaveCriticalSection(&mutex_native_handle); + WaitForSingleObject(hEvent, INFINITE); + EnterCriticalSection(&mutex_native_handle); + InterlockedDecrement(&cWaiters); +# endif #else pthread_cond_wait(&_native_handle, &mutex_native_handle); #endif } - - protected: - native_handle_type _native_handle; }; /** - * Same interface as boost::thread_specific_ptr. + * Same interface as std::thread */ - template - class thread_specific_ptr - { - private: -#ifdef _WIN32 - DWORD dwTlsIndex; -#else - pthread_key_t key; - - static void destructor(void *ptr) { - delete static_cast(ptr); - } -#endif - + class thread { public: - thread_specific_ptr(void) { -#ifdef _WIN32 - dwTlsIndex = TlsAlloc(); -#else - pthread_key_create(&key, &destructor); -#endif - } - - ~thread_specific_ptr() { #ifdef _WIN32 - TlsFree(dwTlsIndex); -#else - pthread_key_delete(key); -#endif - } - - T* get(void) const { - void *ptr; -#ifdef _WIN32 - ptr = TlsGetValue(dwTlsIndex); + typedef HANDLE native_handle_type; #else - ptr = pthread_getspecific(key); + typedef pthread_t native_handle_type; #endif - return static_cast(ptr); - } - T* operator -> (void) const + inline + thread() : + _native_handle(0) { - return get(); } - T& operator * (void) const + inline + thread(const thread &other) : + _native_handle(other._native_handle) { - return *get(); - } - - void reset(T* new_value=0) { - T * old_value = get(); - set(new_value); - if (old_value) { - delete old_value; - } - } - - T* release (void) { - T * old_value = get(); - set(0); - return old_value; } -private: - void set(T* new_value) { -#ifdef _WIN32 - TlsSetValue(dwTlsIndex, new_value); -#else - pthread_setspecific(key, new_value); -#endif - } - }; - - - /** - * Same interface as std::thread - */ - class thread { - public: -#ifdef _WIN32 - typedef HANDLE native_handle_type; -#else - typedef pthread_t native_handle_type; -#endif - template< class Function, class Arg > explicit thread( Function& f, Arg arg ) { #ifdef _WIN32 - /* FIXME */ DWORD id = 0; _native_handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)f, (LPVOID)arg, 0, &id); #else - pthread_create(&_native_handle, NULL, f, arg); + pthread_create(&_native_handle, NULL, (void *(*) (void *))f, (void *)arg); #endif } + inline bool + joinable(void) const { + return _native_handle != 0; + } + inline void join() { #ifdef _WIN32