X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=common%2Fos_thread.hpp;h=5fbdaabf274e0f51304b209f807b133bcb71d55e;hb=58167d7abcd4159c5524ceca67f0ec58c96b0af7;hp=e5eb19d3604c8dd61c47e5ccd22c4b57f1f72e28;hpb=e86f5a2f9b1e57ee2535a285f6385878c78cf0ea;p=apitrace diff --git a/common/os_thread.hpp b/common/os_thread.hpp index e5eb19d..5fbdaab 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 @@ -39,6 +39,24 @@ #include #endif + +/** + * Compiler TLS. + * + * See also: + * - http://gcc.gnu.org/onlinedocs/gcc-4.6.3/gcc/Thread_002dLocal.html + * - http://msdn.microsoft.com/en-us/library/9w1sdazb.aspx + */ +#if defined(_MSC_VER) +# define thread_specific __declspec(thread) +#elif defined(__GNUC__) +# define thread_specific __thread +#else +# define thread_specific +# error "Unsupported compiler" +#endif + + namespace os { @@ -187,14 +205,14 @@ namespace os { { public: #ifdef _WIN32 - /* FIXME */ + typedef CONDITION_VARIABLE native_handle_type; #else typedef pthread_cond_t native_handle_type; #endif condition_variable() { #ifdef _WIN32 - /* FIXME */ + InitializeConditionVariable(&_native_handle); #else pthread_cond_init(&_native_handle, NULL); #endif @@ -202,7 +220,7 @@ namespace os { ~condition_variable() { #ifdef _WIN32 - /* FIXME */ + /* No-op */ #else pthread_cond_destroy(&_native_handle); #endif @@ -211,7 +229,7 @@ namespace os { inline void signal(void) { #ifdef _WIN32 - /* FIXME */ + WakeConditionVariable(&_native_handle); #else pthread_cond_signal(&_native_handle); #endif @@ -219,10 +237,12 @@ namespace os { 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, &lock.mutex()->native_handle()); + pthread_cond_wait(&_native_handle, &mutex_native_handle); #endif } @@ -287,18 +307,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, ( void *(*) (void *))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_ */