summaryrefslogtreecommitdiffstats
path: root/libcxx/include/thread
diff options
context:
space:
mode:
authorHoward Hinnant <hhinnant@apple.com>2010-08-27 20:10:19 +0000
committerHoward Hinnant <hhinnant@apple.com>2010-08-27 20:10:19 +0000
commit167fd1084bcb59dc26d3d3e9b993723800c478b9 (patch)
tree86321cc0089272615b6826ed3c3cc499206e283f /libcxx/include/thread
parent212a492063944c97b20e009100c67c946644194c (diff)
downloadbcm5719-llvm-167fd1084bcb59dc26d3d3e9b993723800c478b9.tar.gz
bcm5719-llvm-167fd1084bcb59dc26d3d3e9b993723800c478b9.zip
future continues ...
llvm-svn: 112284
Diffstat (limited to 'libcxx/include/thread')
-rw-r--r--libcxx/include/thread82
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;
OpenPOWER on IntegriCloud