diff options
| author | Howard Hinnant <hhinnant@apple.com> | 2010-08-27 20:10:19 +0000 |
|---|---|---|
| committer | Howard Hinnant <hhinnant@apple.com> | 2010-08-27 20:10:19 +0000 |
| commit | 167fd1084bcb59dc26d3d3e9b993723800c478b9 (patch) | |
| tree | 86321cc0089272615b6826ed3c3cc499206e283f /libcxx/include/thread | |
| parent | 212a492063944c97b20e009100c67c946644194c (diff) | |
| download | bcm5719-llvm-167fd1084bcb59dc26d3d3e9b993723800c478b9.tar.gz bcm5719-llvm-167fd1084bcb59dc26d3d3e9b993723800c478b9.zip | |
future continues ...
llvm-svn: 112284
Diffstat (limited to 'libcxx/include/thread')
| -rw-r--r-- | libcxx/include/thread | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/libcxx/include/thread b/libcxx/include/thread index fffd2df6670..123c472c85b 100644 --- a/libcxx/include/thread +++ b/libcxx/include/thread @@ -103,6 +103,68 @@ void sleep_for(const chrono::duration<Rep, Period>& rel_time); _LIBCPP_BEGIN_NAMESPACE_STD +template <class _Tp> +class __thread_specific_ptr +{ + pthread_key_t __key_; + + __thread_specific_ptr(const __thread_specific_ptr&); + __thread_specific_ptr& operator=(const __thread_specific_ptr&); + + static void __at_thread_exit(void*); +public: + typedef _Tp* pointer; + + __thread_specific_ptr(); + ~__thread_specific_ptr(); + + pointer get() const {return static_cast<_Tp*>(pthread_getspecific(__key_));} + pointer operator*() const {return *get();} + pointer operator->() const {return get();} + pointer release(); + void reset(pointer __p = nullptr); +}; + +template <class _Tp> +void +__thread_specific_ptr<_Tp>::__at_thread_exit(void* __p) +{ + delete static_cast<pointer>(__p); +} + +template <class _Tp> +__thread_specific_ptr<_Tp>::__thread_specific_ptr() +{ + int __ec = pthread_key_create(&__key_, &__thread_specific_ptr::__at_thread_exit); + if (__ec) + throw system_error(error_code(__ec, system_category()), + "__thread_specific_ptr construction failed"); +} + +template <class _Tp> +__thread_specific_ptr<_Tp>::~__thread_specific_ptr() +{ + pthread_key_delete(__key_); +} + +template <class _Tp> +typename __thread_specific_ptr<_Tp>::pointer +__thread_specific_ptr<_Tp>::release() +{ + pointer __p = get(); + pthread_setspecific(__key_, 0); + return __p; +} + +template <class _Tp> +void +__thread_specific_ptr<_Tp>::reset(pointer __p) +{ + pointer __p_old = get(); + pthread_setspecific(__key_, __p); + delete __p_old; +} + class thread; class __thread_id; @@ -219,10 +281,30 @@ public: static unsigned hardware_concurrency(); }; +class __assoc_sub_state; + +class __thread_struct_imp; + +class __thread_struct +{ + __thread_struct_imp* __p_; + + __thread_struct(const __thread_struct&); + __thread_struct& operator=(const __thread_struct&); +public: + __thread_struct(); + ~__thread_struct(); + + void __make_ready_at_thread_exit(__assoc_sub_state*); +}; + +extern __thread_specific_ptr<__thread_struct> __thread_local_data; + template <class _F> void* __thread_proxy(void* __vp) { + __thread_local_data.reset(new __thread_struct); std::unique_ptr<_F> __p(static_cast<_F*>(__vp)); (*__p)(); return nullptr; |

