summaryrefslogtreecommitdiffstats
path: root/libcxx/src
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/src
parent212a492063944c97b20e009100c67c946644194c (diff)
downloadbcm5719-llvm-167fd1084bcb59dc26d3d3e9b993723800c478b9.tar.gz
bcm5719-llvm-167fd1084bcb59dc26d3d3e9b993723800c478b9.zip
future continues ...
llvm-svn: 112284
Diffstat (limited to 'libcxx/src')
-rw-r--r--libcxx/src/future.cpp157
-rw-r--r--libcxx/src/thread.cpp55
2 files changed, 212 insertions, 0 deletions
diff --git a/libcxx/src/future.cpp b/libcxx/src/future.cpp
index f9547c6609e..82b9b60ee4e 100644
--- a/libcxx/src/future.cpp
+++ b/libcxx/src/future.cpp
@@ -60,4 +60,161 @@ future_error::future_error(error_code __ec)
{
}
+void
+__assoc_sub_state::__on_zero_shared()
+{
+ delete this;
+}
+
+void
+__assoc_sub_state::set_value()
+{
+ unique_lock<mutex> __lk(__mut_);
+ if (__has_value())
+ throw future_error(make_error_code(future_errc::promise_already_satisfied));
+ __state_ |= __constructed | ready;
+ __lk.unlock();
+ __cv_.notify_all();
+}
+
+void
+__assoc_sub_state::set_value_at_thread_exit()
+{
+ unique_lock<mutex> __lk(__mut_);
+ if (__has_value())
+ throw future_error(make_error_code(future_errc::promise_already_satisfied));
+ __state_ |= __constructed;
+ __thread_local_data->__make_ready_at_thread_exit(this);
+ __lk.unlock();
+}
+
+void
+__assoc_sub_state::set_exception(exception_ptr __p)
+{
+ unique_lock<mutex> __lk(__mut_);
+ if (__has_value())
+ throw future_error(make_error_code(future_errc::promise_already_satisfied));
+ __exception_ = __p;
+ __state_ |= ready;
+ __lk.unlock();
+ __cv_.notify_all();
+}
+
+void
+__assoc_sub_state::set_exception_at_thread_exit(exception_ptr __p)
+{
+ unique_lock<mutex> __lk(__mut_);
+ if (__has_value())
+ throw future_error(make_error_code(future_errc::promise_already_satisfied));
+ __exception_ = __p;
+ __thread_local_data->__make_ready_at_thread_exit(this);
+ __lk.unlock();
+}
+
+void
+__assoc_sub_state::__make_ready()
+{
+ unique_lock<mutex> __lk(__mut_);
+ __state_ |= ready;
+ __lk.unlock();
+ __cv_.notify_all();
+}
+
+void
+__assoc_sub_state::copy()
+{
+ unique_lock<mutex> __lk(__mut_);
+ while (!__is_ready())
+ __cv_.wait(__lk);
+ if (__exception_ != nullptr)
+ rethrow_exception(__exception_);
+}
+
+void
+__assoc_sub_state::wait() const
+{
+ unique_lock<mutex> __lk(__mut_);
+ while (!__is_ready())
+ __cv_.wait(__lk);
+}
+
+future<void>::future(__assoc_sub_state* __state)
+ : __state_(__state)
+{
+ if (__state_->__has_future_attached())
+ throw future_error(make_error_code(future_errc::future_already_retrieved));
+ __state_->__add_shared();
+}
+
+future<void>::~future()
+{
+ if (__state_)
+ __state_->__release_shared();
+}
+
+void
+future<void>::get()
+{
+ __assoc_sub_state* __s = __state_;
+ __state_ = nullptr;
+ return __s->copy();
+}
+
+promise<void>::promise()
+ : __state_(new __assoc_sub_state)
+{
+}
+
+promise<void>::~promise()
+{
+ if (__state_)
+ {
+ if (!__state_->__has_value() && __state_->use_count() > 1)
+ __state_->set_exception(make_exception_ptr(
+ future_error(make_error_code(future_errc::broken_promise))
+ ));
+ __state_->__release_shared();
+ }
+}
+
+future<void>
+promise<void>::get_future()
+{
+ if (__state_ == nullptr)
+ throw future_error(make_error_code(future_errc::no_state));
+ return future<void>(__state_);
+}
+
+void
+promise<void>::set_value()
+{
+ if (__state_ == nullptr)
+ throw future_error(make_error_code(future_errc::no_state));
+ __state_->set_value();
+}
+
+void
+promise<void>::set_exception(exception_ptr __p)
+{
+ if (__state_ == nullptr)
+ throw future_error(make_error_code(future_errc::no_state));
+ __state_->set_exception(__p);
+}
+
+void
+promise<void>::set_value_at_thread_exit()
+{
+ if (__state_ == nullptr)
+ throw future_error(make_error_code(future_errc::no_state));
+ __state_->set_value_at_thread_exit();
+}
+
+void
+promise<void>::set_exception_at_thread_exit(exception_ptr __p)
+{
+ if (__state_ == nullptr)
+ throw future_error(make_error_code(future_errc::no_state));
+ __state_->set_exception_at_thread_exit(__p);
+}
+
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/src/thread.cpp b/libcxx/src/thread.cpp
index 992976500e5..f8407067270 100644
--- a/libcxx/src/thread.cpp
+++ b/libcxx/src/thread.cpp
@@ -9,6 +9,8 @@
#include "thread"
#include "exception"
+#include "vector"
+#include "future"
#include <sys/types.h>
#include <sys/sysctl.h>
@@ -81,4 +83,57 @@ sleep_for(const chrono::nanoseconds& ns)
} // this_thread
+__thread_specific_ptr<__thread_struct> __thread_local_data;
+
+// __thread_struct_imp
+
+class __thread_struct_imp
+{
+ typedef vector<__assoc_sub_state*> _AsyncStates;
+ _AsyncStates async_states_;
+
+ __thread_struct_imp(const __thread_struct_imp&);
+ __thread_struct_imp& operator=(const __thread_struct_imp&);
+public:
+ __thread_struct_imp() {}
+ ~__thread_struct_imp();
+
+ void __make_ready_at_thread_exit(__assoc_sub_state* __s);
+};
+
+__thread_struct_imp::~__thread_struct_imp()
+{
+ for (_AsyncStates::iterator i = async_states_.begin(), e = async_states_.end();
+ i != e; ++i)
+ {
+ (*i)->__make_ready();
+ (*i)->__release_shared();
+ }
+}
+
+void
+__thread_struct_imp::__make_ready_at_thread_exit(__assoc_sub_state* __s)
+{
+ async_states_.push_back(__s);
+ __s->__add_shared();
+}
+
+// __thread_struct
+
+__thread_struct::__thread_struct()
+ : __p_(new __thread_struct_imp)
+{
+}
+
+__thread_struct::~__thread_struct()
+{
+ delete __p_;
+}
+
+void
+__thread_struct::__make_ready_at_thread_exit(__assoc_sub_state* __s)
+{
+ __p_->__make_ready_at_thread_exit(__s);
+}
+
_LIBCPP_END_NAMESPACE_STD
OpenPOWER on IntegriCloud