X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=common%2Fos_thread.hpp;h=3aeeee4849551e360bcc4db44335e9251603d415;hb=c5cd3565d87b910bf5966d5e5c66ce722fcf25ae;hp=7349255525276b47b36c3b5ba5aa7e3c4f4b6d81;hpb=5926761f1682c26266a78f2674e58beff3bfae88;p=apitrace diff --git a/common/os_thread.hpp b/common/os_thread.hpp index 7349255..3aeeee4 100644 --- a/common/os_thread.hpp +++ b/common/os_thread.hpp @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2011 Jose Fonseca + * Copyright 2011-2012 Jose Fonseca * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -32,6 +32,7 @@ #ifndef _OS_THREAD_HPP_ #define _OS_THREAD_HPP_ + #ifdef _WIN32 #include #else @@ -41,6 +42,200 @@ namespace os { + /** + * 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 + + _base_mutex(void) { +#ifdef _WIN32 + InitializeCriticalSection(&_native_handle); +#else + 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 + } + + ~_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 + } + + 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 + } + }; + + + /** + * Same interface as std::recursive_mutex. + */ + class recursive_mutex : public _base_mutex + { + public: + inline + recursive_mutex(void) { +#ifdef _WIN32 + InitializeCriticalSection(&_native_handle); +#else + 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 + } + }; + + + /** + * Same interface as std::unique_lock; + */ + template< class Mutex > + class unique_lock + { + public: + typedef Mutex mutex_type; + + inline explicit + unique_lock(mutex_type & mutex) : + _mutex(&mutex) + { + _mutex->lock(); + } + + inline + ~unique_lock() { + _mutex->unlock(); + } + + inline void + lock() { + _mutex->lock(); + } + + inline void + unlock() { + _mutex->unlock(); + } + + mutex_type * + mutex() const { + return _mutex; + } + + protected: + mutex_type *_mutex; + }; + + + /** + * Same interface as std::condition_variable + */ + class condition_variable + { + public: +#ifdef _WIN32 + typedef CONDITION_VARIABLE native_handle_type; +#else + typedef pthread_cond_t native_handle_type; +#endif + + condition_variable() { +#ifdef _WIN32 + InitializeConditionVariable(&_native_handle); +#else + pthread_cond_init(&_native_handle, NULL); +#endif + } + + ~condition_variable() { +#ifdef _WIN32 + /* No-op */ +#else + pthread_cond_destroy(&_native_handle); +#endif + } + + inline void + signal(void) { +#ifdef _WIN32 + WakeConditionVariable(&_native_handle); +#else + pthread_cond_signal(&_native_handle); +#endif + } + + inline void + wait(unique_lock & lock) { + mutex::native_handle_type & mutex_native_handle = lock.mutex()->native_handle(); +#ifdef _WIN32 + /* FIXME */ + SleepConditionVariableCS(&_native_handle, &mutex_native_handle, INFINITE); +#else + pthread_cond_wait(&_native_handle, &mutex_native_handle); +#endif + } + + protected: + native_handle_type _native_handle; + }; + + + /** + * Same interface as boost::thread_specific_ptr. + */ template class thread_specific_ptr { @@ -94,17 +289,74 @@ namespace os { 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 - if (old_value) { - delete old_value; - } } }; + + /** + * 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); +#endif + } + + inline void + join() { +#ifdef _WIN32 + WaitForSingleObject(_native_handle, INFINITE); +#else + pthread_join(_native_handle, NULL); +#endif + } + + private: + native_handle_type _native_handle; + +#if 0 +#ifdef _WIN32 + template< class Function, class Arg > + static DWORD WINAPI + ThreadProc(LPVOID lpParameter) { + + ); +#endif +#endif + }; + } /* namespace os */ #endif /* _OS_THREAD_HPP_ */