diff options
author | David Chisnall <dchisnall@pathscale.com> | 2011-11-24 17:02:08 +0000 |
---|---|---|
committer | David Chisnall <dchisnall@pathscale.com> | 2011-11-24 17:02:08 +0000 |
commit | 0f31431b38936983c803c10b241f55299818baad (patch) | |
tree | dab15dab92ad9689d085f915ea27a65c69c6f80e | |
parent | 1be67aa8295314fb794c4e933d9bb7c7c33e0ca4 (diff) | |
download | libcxxrt-0f31431b38936983c803c10b241f55299818baad.tar.gz libcxxrt-0f31431b38936983c803c10b241f55299818baad.tar.bz2 libcxxrt-0f31431b38936983c803c10b241f55299818baad.tar.xz |
Add fake TLS support so that we work for single-threaded programs when not linked to pthread.
-rw-r--r-- | src/exception.cc | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/src/exception.cc b/src/exception.cc index abf6a10..0896354 100644 --- a/src/exception.cc +++ b/src/exception.cc @@ -289,11 +289,24 @@ static void thread_cleanup(void* thread_info) static pthread_once_t once_control = PTHREAD_ONCE_INIT; /** + * We may not be linked against a full pthread implementation. If we're not, + * then we need to fake the thread-local storage by storing 'thread-local' + * things in a global. + */ +static bool fakeTLS; +/** + * Thread-local storage for a single-threaded program. + */ +static __cxa_thread_info singleThreadInfo; +/** * Initialise eh_key. */ static void init_key(void) { pthread_key_create(&eh_key, thread_cleanup); + pthread_setspecific(eh_key, (void*)0x42); + fakeTLS = (pthread_getspecific(eh_key) != (void*)0x42); + pthread_setspecific(eh_key, 0); } /** @@ -301,7 +314,11 @@ static void init_key(void) */ static __cxa_thread_info *thread_info() { - pthread_once(&once_control, init_key); + if (pthread_once(&once_control, init_key)) + { + fakeTLS = true; + } + if (fakeTLS) { return &singleThreadInfo; } __cxa_thread_info *info = (__cxa_thread_info*)pthread_getspecific(eh_key); if (0 == info) { @@ -316,6 +333,7 @@ static __cxa_thread_info *thread_info() */ static __cxa_thread_info *thread_info_fast() { + if (fakeTLS) { return &singleThreadInfo; } return (__cxa_thread_info*)pthread_getspecific(eh_key); } /** |