X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=common%2Fos_thread.hpp;h=c4bc130d4693b7d9bb201da8675543acdcd4659d;hb=82311849bbba61d0f1c49bd83abb9ffd52033bf2;hp=727ad6a484ff0c94a1e8d76bd4a88a3dd846dc15;hpb=0af9670e1d6fe6e9dc6d38c7b28e18a5fea7d009;p=apitrace diff --git a/common/os_thread.hpp b/common/os_thread.hpp index 727ad6a..c4bc130 100644 --- a/common/os_thread.hpp +++ b/common/os_thread.hpp @@ -32,6 +32,7 @@ #ifndef _OS_THREAD_HPP_ #define _OS_THREAD_HPP_ + #ifdef _WIN32 #include #else @@ -41,37 +42,169 @@ namespace os { - namespace thread { + /** + * Base class for mutex and recursive_mutex. + */ + class _base_mutex + { + public: +#ifdef _WIN32 + typedef CRITICAL_SECTION native_handle_type; +#else + typedef pthread_mutex_t native_handle_type; +#endif - /** - * Thread ID - * - * XXX: Actually C++11 thread::id is not an integral type, but we rely on that. - */ + _base_mutex(void) { #ifdef _WIN32 - typedef DWORD id; + InitializeCriticalSection(&_native_handle); #else - typedef pthread_t id; + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&_native_handle, &attr); + pthread_mutexattr_destroy(&attr); #endif + } - } /* namespace thread */ + ~_base_mutex() { +#ifdef _WIN32 + DeleteCriticalSection(&_native_handle); +#else + pthread_mutex_destroy(&_native_handle); +#endif + } + inline void + lock(void) { +#ifdef _WIN32 + EnterCriticalSection(&_native_handle); +#else + pthread_mutex_lock(&_native_handle); +#endif + } - namespace this_thread { + inline void + unlock(void) { +#ifdef _WIN32 + LeaveCriticalSection(&_native_handle); +#else + pthread_mutex_unlock(&_native_handle); +#endif + } + + native_handle_type & native_handle() { + return _native_handle; + } + + protected: + native_handle_type _native_handle; + }; + + + /** + * Same interface as std::mutex. + */ + class mutex : public _base_mutex + { + public: + inline + mutex(void) { +#ifdef _WIN32 + InitializeCriticalSection(&_native_handle); +#else + pthread_mutex_init(&_native_handle, NULL); +#endif + } + }; - /** - * Get current thread ID. - */ - inline thread::id - get_id(void) { + + /** + * Same interface as std::recursive_mutex. + */ + class recursive_mutex : public _base_mutex + { + public: + inline + recursive_mutex(void) { #ifdef _WIN32 - return GetCurrentThreadId(); + InitializeCriticalSection(&_native_handle); #else - return pthread_self(); + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&_native_handle, &attr); + pthread_mutexattr_destroy(&attr); #endif } + }; + - } /* namespace this_thread */ + /** + * Same interface as boost::thread_specific_ptr. + */ + 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 + + 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); +#else + ptr = pthread_getspecific(key); +#endif + return static_cast(ptr); + } + + T* operator -> (void) const + { + return get(); + } + + T& operator * (void) const + { + return *get(); + } + + void reset(T* new_value=0) { + T * old_value = get(); +#ifdef _WIN32 + TlsSetValue(dwTlsIndex, new_value); +#else + pthread_setspecific(key, new_value); +#endif + if (old_value) { + delete old_value; + } + } + }; } /* namespace os */