diff options
Diffstat (limited to 'indra/llcommon')
-rwxr-xr-x | indra/llcommon/llhash.h | 43 | ||||
-rwxr-xr-x | indra/llcommon/llpreprocessor.h | 5 | ||||
-rwxr-xr-x | indra/llcommon/llthread.cpp | 18 | ||||
-rw-r--r-- | indra/llcommon/llthreadlocalstorage.h | 41 | ||||
-rwxr-xr-x | indra/llcommon/tests/llframetimer_test.cpp | 27 |
5 files changed, 35 insertions, 99 deletions
diff --git a/indra/llcommon/llhash.h b/indra/llcommon/llhash.h index c077ebe93f..4b58e81565 100755 --- a/indra/llcommon/llhash.h +++ b/indra/llcommon/llhash.h @@ -27,26 +27,7 @@ #ifndef LL_LLHASH_H #define LL_LLHASH_H -#include "llpreprocessor.h" // for GCC_VERSION - -#if (LL_WINDOWS) -#include <hash_map> -#include <algorithm> -#elif LL_DARWIN || LL_LINUX -# if GCC_VERSION >= 40300 // gcc 4.3 and up -# include <backward/hashtable.h> -# elif GCC_VERSION >= 30400 // gcc 3.4 and up -# include <ext/hashtable.h> -# elif __GNUC__ >= 3 -# include <ext/stl_hashtable.h> -# else -# include <hashtable.h> -# endif -#elif LL_SOLARIS -#include <ext/hashtable.h> -#else -#error Please define your platform. -#endif +#include <boost/functional/hash.hpp> // Warning - an earlier template-based version of this routine did not do // the correct thing on Windows. Since this is only used to get @@ -55,17 +36,17 @@ inline size_t llhash( const char * value ) { -#if LL_WINDOWS - return stdext::hash_value(value); -#elif ( (defined _STLPORT_VERSION) || ((LL_LINUX) && (__GNUC__ <= 2)) ) - std::hash<const char *> H; - return H(value); -#elif LL_DARWIN || LL_LINUX || LL_SOLARIS - __gnu_cxx::hash<const char *> H; - return H(value); -#else -#error Please define your platform. -#endif + // boost::hash is defined for std::string and for char, but there's no + // special overload for const char*. The lazy approach would be to + // instantiate a std::string and take its hash, but that might be more + // overhead than our callers want. Or we could use boost::hash_range() -- + // but that would require a preliminary pass over the value to determine + // the end iterator. Instead, use boost::hash_combine() to hash individual + // characters. + std::size_t seed = 0; + for ( ; *value; ++value) + boost::hash_combine(seed, *value); + return seed; } #endif diff --git a/indra/llcommon/llpreprocessor.h b/indra/llcommon/llpreprocessor.h index 309165da7f..2c4bcc91f6 100755 --- a/indra/llcommon/llpreprocessor.h +++ b/indra/llcommon/llpreprocessor.h @@ -101,6 +101,11 @@ #endif +#if LL_WINDOWS +# define LL_THREAD_LOCAL __declspec(thread) +#else +# define LL_THREAD_LOCAL __thread +#endif // Static linking with apr on windows needs to be declared. #if LL_WINDOWS && !LL_COMMON_LINK_SHARED diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index 51c89e1eaf..c3f235c6ee 100755 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -92,13 +92,7 @@ void set_thread_name( DWORD dwThreadID, const char* threadName) // //---------------------------------------------------------------------------- -#if LL_DARWIN -// statically allocated thread local storage not supported in Darwin executable formats -#elif LL_WINDOWS -U32 __declspec(thread) sThreadID = 0; -#elif LL_LINUX -U32 __thread sThreadID = 0; -#endif +U32 LL_THREAD_LOCAL sThreadID = 0; U32 LLThread::sIDIter = 0; @@ -115,9 +109,7 @@ LL_COMMON_API void assert_main_thread() void LLThread::registerThreadID() { -#if !LL_DARWIN sThreadID = ++sIDIter; -#endif } // @@ -134,9 +126,7 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap // for now, hard code all LLThreads to report to single master thread recorder, which is known to be running on main thread threadp->mRecorder = new LLTrace::ThreadRecorder(*LLTrace::get_master_thread_recorder()); -#if !LL_DARWIN sThreadID = threadp->mID; -#endif // Run the user supplied function threadp->run(); @@ -347,13 +337,7 @@ void LLThread::setQuitting() // static U32 LLThread::currentID() { -#if LL_DARWIN - // statically allocated thread local storage not supported in Darwin executable formats - return (U32)apr_os_thread_current(); -#else return sThreadID; -#endif - } // static diff --git a/indra/llcommon/llthreadlocalstorage.h b/indra/llcommon/llthreadlocalstorage.h index ec3b52c8cb..3b5786023f 100644 --- a/indra/llcommon/llthreadlocalstorage.h +++ b/indra/llcommon/llthreadlocalstorage.h @@ -130,56 +130,19 @@ class LLThreadLocalSingletonPointer public: LL_FORCE_INLINE static DERIVED_TYPE* getInstance() { -#if LL_DARWIN - createTLSKey(); - return (DERIVED_TYPE*)pthread_getspecific(sInstanceKey); -#else return sInstance; -#endif } static void setInstance(DERIVED_TYPE* instance) { -#if LL_DARWIN - createTLSKey(); - pthread_setspecific(sInstanceKey, (void*)instance); -#else sInstance = instance; -#endif } private: - -#if LL_WINDOWS - static __declspec(thread) DERIVED_TYPE* sInstance; -#elif LL_LINUX - static __thread DERIVED_TYPE* sInstance; -#elif LL_DARWIN - static void TLSError() - { - LL_ERRS() << "Could not create thread local storage" << LL_ENDL; - } - static void createTLSKey() - { - static S32 key_created = pthread_key_create(&sInstanceKey, NULL); - if (key_created != 0) - { - LL_ERRS() << "Could not create thread local storage" << LL_ENDL; - } - } - static pthread_key_t sInstanceKey; -#endif + static LL_THREAD_LOCAL DERIVED_TYPE* sInstance; }; -#if LL_WINDOWS -template<typename DERIVED_TYPE> -__declspec(thread) DERIVED_TYPE* LLThreadLocalSingletonPointer<DERIVED_TYPE>::sInstance = NULL; -#elif LL_LINUX -template<typename DERIVED_TYPE> -__thread DERIVED_TYPE* LLThreadLocalSingletonPointer<DERIVED_TYPE>::sInstance = NULL; -#elif LL_DARWIN template<typename DERIVED_TYPE> -pthread_key_t LLThreadLocalSingletonPointer<DERIVED_TYPE>::sInstanceKey; -#endif +LL_THREAD_LOCAL DERIVED_TYPE* LLThreadLocalSingletonPointer<DERIVED_TYPE>::sInstance = NULL; #endif // LL_LLTHREADLOCALSTORAGE_H diff --git a/indra/llcommon/tests/llframetimer_test.cpp b/indra/llcommon/tests/llframetimer_test.cpp index 8ac1c91a3a..46fc4ce93a 100755 --- a/indra/llcommon/tests/llframetimer_test.cpp +++ b/indra/llcommon/tests/llframetimer_test.cpp @@ -88,21 +88,24 @@ namespace tut seconds_since_epoch += 2.0; LLFrameTimer timer; timer.setExpiryAt(seconds_since_epoch); - ensure("timer not expired on create", !timer.hasExpired()); - int ii; - for(ii = 0; ii < 10; ++ii) + /* + * Note that the ms_sleep(200) below is only guaranteed to return + * in 200ms _or_more_, so it should be true that by the 10th + * iteration we've gotten to the 2 seconds requested above + * and the timer should expire, but it can expire in fewer iterations + * if one or more of the ms_sleep calls takes longer. + * (as it did when we moved to Mac OS X 10.10) + */ + int iterations_until_expiration = 0; + while ( !timer.hasExpired() ) { - ms_sleep(150); - LLFrameTimer::updateFrameTime(); - } - ensure("timer not expired after a bit", !timer.hasExpired()); - for(ii = 0; ii < 10; ++ii) - { - ms_sleep(100); - LLFrameTimer::updateFrameTime(); + ms_sleep(200); + LLFrameTimer::updateFrameTime(); + iterations_until_expiration++; } - ensure("timer expired", timer.hasExpired()); + ensure("timer took too long to expire", iterations_until_expiration <= 10); } + /* template<> template<> void frametimer_object_t::test<4>() |