diff options
Diffstat (limited to 'libcxx/test/std/thread/thread.condition')
30 files changed, 1881 insertions, 0 deletions
diff --git a/libcxx/test/std/thread/thread.condition/cv_status.pass.cpp b/libcxx/test/std/thread/thread.condition/cv_status.pass.cpp new file mode 100644 index 00000000000..fe5fa05ad24 --- /dev/null +++ b/libcxx/test/std/thread/thread.condition/cv_status.pass.cpp @@ -0,0 +1,23 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <condition_variable> + +// enum class cv_status { no_timeout, timeout }; + +#include <condition_variable> +#include <cassert> + +int main() +{ + assert(static_cast<int>(std::cv_status::no_timeout) == 0); + assert(static_cast<int>(std::cv_status::timeout) == 1); +} diff --git a/libcxx/test/std/thread/thread.condition/notify_all_at_thread_exit.pass.cpp b/libcxx/test/std/thread/thread.condition/notify_all_at_thread_exit.pass.cpp new file mode 100644 index 00000000000..2b8772f92ed --- /dev/null +++ b/libcxx/test/std/thread/thread.condition/notify_all_at_thread_exit.pass.cpp @@ -0,0 +1,44 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <condition_variable> + +// void +// notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk); + +#include <condition_variable> +#include <mutex> +#include <thread> +#include <chrono> +#include <cassert> + +std::condition_variable cv; +std::mutex mut; + +typedef std::chrono::milliseconds ms; +typedef std::chrono::high_resolution_clock Clock; + +void func() +{ + std::unique_lock<std::mutex> lk(mut); + std::notify_all_at_thread_exit(cv, std::move(lk)); + std::this_thread::sleep_for(ms(300)); +} + +int main() +{ + std::unique_lock<std::mutex> lk(mut); + std::thread(func).detach(); + Clock::time_point t0 = Clock::now(); + cv.wait(lk); + Clock::time_point t1 = Clock::now(); + assert(t1-t0 > ms(250)); +} diff --git a/libcxx/test/std/thread/thread.condition/thread.condition.condvar/assign.fail.cpp b/libcxx/test/std/thread/thread.condition/thread.condition.condvar/assign.fail.cpp new file mode 100644 index 00000000000..e88550c5b8a --- /dev/null +++ b/libcxx/test/std/thread/thread.condition/thread.condition.condvar/assign.fail.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <condition_variable> + +// class condition_variable; + +// condition_variable& operator=(const condition_variable&) = delete; + +#include <condition_variable> +#include <cassert> + +int main() +{ + std::condition_variable cv0; + std::condition_variable cv1; + cv1 = cv0; +} diff --git a/libcxx/test/std/thread/thread.condition/thread.condition.condvar/copy.fail.cpp b/libcxx/test/std/thread/thread.condition/thread.condition.condvar/copy.fail.cpp new file mode 100644 index 00000000000..24d6ee0e71d --- /dev/null +++ b/libcxx/test/std/thread/thread.condition/thread.condition.condvar/copy.fail.cpp @@ -0,0 +1,23 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <condition_variable> + +// class condition_variable; + +// condition_variable(const condition_variable&) = delete; + +#include <condition_variable> +#include <cassert> + +int main() +{ + std::condition_variable cv0; + std::condition_variable cv1(cv0); +} diff --git a/libcxx/test/std/thread/thread.condition/thread.condition.condvar/default.pass.cpp b/libcxx/test/std/thread/thread.condition/thread.condition.condvar/default.pass.cpp new file mode 100644 index 00000000000..6f43564c3b3 --- /dev/null +++ b/libcxx/test/std/thread/thread.condition/thread.condition.condvar/default.pass.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <condition_variable> + +// class condition_variable; + +// condition_variable(); + +#include <condition_variable> +#include <cassert> + +int main() +{ + std::condition_variable cv; +} diff --git a/libcxx/test/std/thread/thread.condition/thread.condition.condvar/destructor.pass.cpp b/libcxx/test/std/thread/thread.condition/thread.condition.condvar/destructor.pass.cpp new file mode 100644 index 00000000000..437ed965b19 --- /dev/null +++ b/libcxx/test/std/thread/thread.condition/thread.condition.condvar/destructor.pass.cpp @@ -0,0 +1,58 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <condition_variable> + +// class condition_variable; + +// ~condition_variable(); + +#include <condition_variable> +#include <mutex> +#include <thread> +#include <cassert> + +std::condition_variable* cv; +std::mutex m; +typedef std::unique_lock<std::mutex> Lock; + +bool f_ready = false; +bool g_ready = false; + +void f() +{ + Lock lk(m); + f_ready = true; + cv->notify_one(); + delete cv; +} + +void g() +{ + Lock lk(m); + g_ready = true; + cv->notify_one(); + while (!f_ready) + cv->wait(lk); +} + +int main() +{ + cv = new std::condition_variable; + std::thread th2(g); + Lock lk(m); + while (!g_ready) + cv->wait(lk); + lk.unlock(); + std::thread th1(f); + th1.join(); + th2.join(); +} diff --git a/libcxx/test/std/thread/thread.condition/thread.condition.condvar/native_handle.pass.cpp b/libcxx/test/std/thread/thread.condition/thread.condition.condvar/native_handle.pass.cpp new file mode 100644 index 00000000000..bf28e01a0e8 --- /dev/null +++ b/libcxx/test/std/thread/thread.condition/thread.condition.condvar/native_handle.pass.cpp @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <condition_variable> + +// class condition_variable; + +// typedef pthread_cond_t* native_handle_type; +// native_handle_type native_handle(); + +#include <condition_variable> +#include <cassert> + +int main() +{ + static_assert((std::is_same<std::condition_variable::native_handle_type, + pthread_cond_t*>::value), ""); + std::condition_variable cv; + std::condition_variable::native_handle_type h = cv.native_handle(); + assert(h != nullptr); +} diff --git a/libcxx/test/std/thread/thread.condition/thread.condition.condvar/notify_all.pass.cpp b/libcxx/test/std/thread/thread.condition/thread.condition.condvar/notify_all.pass.cpp new file mode 100644 index 00000000000..fd80ee99c96 --- /dev/null +++ b/libcxx/test/std/thread/thread.condition/thread.condition.condvar/notify_all.pass.cpp @@ -0,0 +1,69 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <condition_variable> + +// class condition_variable; + +// void notify_all(); + +#include <condition_variable> +#include <mutex> +#include <thread> +#include <cassert> + +std::condition_variable cv; +std::mutex mut; + +int test0 = 0; +int test1 = 0; +int test2 = 0; + +void f1() +{ + std::unique_lock<std::mutex> lk(mut); + assert(test1 == 0); + while (test1 == 0) + cv.wait(lk); + assert(test1 == 1); + test1 = 2; +} + +void f2() +{ + std::unique_lock<std::mutex> lk(mut); + assert(test2 == 0); + while (test2 == 0) + cv.wait(lk); + assert(test2 == 1); + test2 = 2; +} + +int main() +{ + std::thread t1(f1); + std::thread t2(f2); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + { + std::unique_lock<std::mutex>lk(mut); + test1 = 1; + test2 = 1; + } + cv.notify_all(); + { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + std::unique_lock<std::mutex>lk(mut); + } + t1.join(); + t2.join(); + assert(test1 == 2); + assert(test2 == 2); +} diff --git a/libcxx/test/std/thread/thread.condition/thread.condition.condvar/notify_one.pass.cpp b/libcxx/test/std/thread/thread.condition/thread.condition.condvar/notify_one.pass.cpp new file mode 100644 index 00000000000..6236a13df80 --- /dev/null +++ b/libcxx/test/std/thread/thread.condition/thread.condition.condvar/notify_one.pass.cpp @@ -0,0 +1,94 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <condition_variable> + +// class condition_variable; + +// void notify_one(); + +#include <condition_variable> +#include <mutex> +#include <thread> +#include <cassert> + +std::condition_variable cv; +std::mutex mut; + +int test0 = 0; +int test1 = 0; +int test2 = 0; + +void f1() +{ + std::unique_lock<std::mutex> lk(mut); + assert(test1 == 0); + while (test1 == 0) + cv.wait(lk); + assert(test1 == 1); + test1 = 2; +} + +void f2() +{ + std::unique_lock<std::mutex> lk(mut); + assert(test2 == 0); + while (test2 == 0) + cv.wait(lk); + assert(test2 == 1); + test2 = 2; +} + +int main() +{ + std::thread t1(f1); + std::thread t2(f2); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + { + std::unique_lock<std::mutex>lk(mut); + test1 = 1; + test2 = 1; + } + cv.notify_one(); + { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + std::unique_lock<std::mutex>lk(mut); + } + if (test1 == 2) + { + t1.join(); + test1 = 0; + } + else if (test2 == 2) + { + t2.join(); + test2 = 0; + } + else + assert(false); + cv.notify_one(); + { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + std::unique_lock<std::mutex>lk(mut); + } + if (test1 == 2) + { + t1.join(); + test1 = 0; + } + else if (test2 == 2) + { + t2.join(); + test2 = 0; + } + else + assert(false); +} diff --git a/libcxx/test/std/thread/thread.condition/thread.condition.condvar/wait.pass.cpp b/libcxx/test/std/thread/thread.condition/thread.condition.condvar/wait.pass.cpp new file mode 100644 index 00000000000..236eecc919a --- /dev/null +++ b/libcxx/test/std/thread/thread.condition/thread.condition.condvar/wait.pass.cpp @@ -0,0 +1,52 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <condition_variable> + +// class condition_variable; + +// void wait(unique_lock<mutex>& lock); + +#include <condition_variable> +#include <mutex> +#include <thread> +#include <cassert> + +std::condition_variable cv; +std::mutex mut; + +int test1 = 0; +int test2 = 0; + +void f() +{ + std::unique_lock<std::mutex> lk(mut); + assert(test2 == 0); + test1 = 1; + cv.notify_one(); + while (test2 == 0) + cv.wait(lk); + assert(test2 != 0); +} + +int main() +{ + std::unique_lock<std::mutex>lk(mut); + std::thread t(f); + assert(test1 == 0); + while (test1 == 0) + cv.wait(lk); + assert(test1 != 0); + test2 = 1; + lk.unlock(); + cv.notify_one(); + t.join(); +} diff --git a/libcxx/test/std/thread/thread.condition/thread.condition.condvar/wait_for.pass.cpp b/libcxx/test/std/thread/thread.condition/thread.condition.condvar/wait_for.pass.cpp new file mode 100644 index 00000000000..ca48eee19d2 --- /dev/null +++ b/libcxx/test/std/thread/thread.condition/thread.condition.condvar/wait_for.pass.cpp @@ -0,0 +1,87 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <condition_variable> + +// class condition_variable; + +// template <class Rep, class Period> +// cv_status +// wait_for(unique_lock<mutex>& lock, +// const chrono::duration<Rep, Period>& rel_time); + +#include <condition_variable> +#include <mutex> +#include <thread> +#include <chrono> +#include <cassert> + +std::condition_variable cv; +std::mutex mut; + +int test1 = 0; +int test2 = 0; + +int runs = 0; + +void f() +{ + typedef std::chrono::system_clock Clock; + typedef std::chrono::milliseconds milliseconds; + std::unique_lock<std::mutex> lk(mut); + assert(test2 == 0); + test1 = 1; + cv.notify_one(); + Clock::time_point t0 = Clock::now(); + while (test2 == 0 && + cv.wait_for(lk, milliseconds(250)) == std::cv_status::no_timeout) + ; + Clock::time_point t1 = Clock::now(); + if (runs == 0) + { + assert(t1 - t0 < milliseconds(250)); + assert(test2 != 0); + } + else + { + assert(t1 - t0 - milliseconds(250) < milliseconds(50)); + assert(test2 == 0); + } + ++runs; +} + +int main() +{ + { + std::unique_lock<std::mutex>lk(mut); + std::thread t(f); + assert(test1 == 0); + while (test1 == 0) + cv.wait(lk); + assert(test1 != 0); + test2 = 1; + lk.unlock(); + cv.notify_one(); + t.join(); + } + test1 = 0; + test2 = 0; + { + std::unique_lock<std::mutex>lk(mut); + std::thread t(f); + assert(test1 == 0); + while (test1 == 0) + cv.wait(lk); + assert(test1 != 0); + lk.unlock(); + t.join(); + } +} diff --git a/libcxx/test/std/thread/thread.condition/thread.condition.condvar/wait_for_pred.pass.cpp b/libcxx/test/std/thread/thread.condition/thread.condition.condvar/wait_for_pred.pass.cpp new file mode 100644 index 00000000000..0ee40d161b7 --- /dev/null +++ b/libcxx/test/std/thread/thread.condition/thread.condition.condvar/wait_for_pred.pass.cpp @@ -0,0 +1,95 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <condition_variable> + +// class condition_variable; + +// template <class Rep, class Period, class Predicate> +// bool +// wait_for(unique_lock<mutex>& lock, +// const chrono::duration<Rep, Period>& rel_time, +// Predicate pred); + +#include <condition_variable> +#include <mutex> +#include <thread> +#include <chrono> +#include <cassert> + +class Pred +{ + int& i_; +public: + explicit Pred(int& i) : i_(i) {} + + bool operator()() {return i_ != 0;} +}; + +std::condition_variable cv; +std::mutex mut; + +int test1 = 0; +int test2 = 0; + +int runs = 0; + +void f() +{ + typedef std::chrono::system_clock Clock; + typedef std::chrono::milliseconds milliseconds; + std::unique_lock<std::mutex> lk(mut); + assert(test2 == 0); + test1 = 1; + cv.notify_one(); + Clock::time_point t0 = Clock::now(); + bool r = cv.wait_for(lk, milliseconds(250), Pred(test2)); + Clock::time_point t1 = Clock::now(); + if (runs == 0) + { + assert(t1 - t0 < milliseconds(250)); + assert(test2 != 0); + } + else + { + assert(t1 - t0 - milliseconds(250) < milliseconds(50)); + assert(test2 == 0); + } + ++runs; +} + +int main() +{ + { + std::unique_lock<std::mutex>lk(mut); + std::thread t(f); + assert(test1 == 0); + while (test1 == 0) + cv.wait(lk); + assert(test1 != 0); + test2 = 1; + lk.unlock(); + cv.notify_one(); + t.join(); + } + test1 = 0; + test2 = 0; + { + std::unique_lock<std::mutex>lk(mut); + std::thread t(f); + assert(test1 == 0); + while (test1 == 0) + cv.wait(lk); + assert(test1 != 0); + lk.unlock(); + t.join(); + } +} diff --git a/libcxx/test/std/thread/thread.condition/thread.condition.condvar/wait_pred.pass.cpp b/libcxx/test/std/thread/thread.condition/thread.condition.condvar/wait_pred.pass.cpp new file mode 100644 index 00000000000..45e0b812416 --- /dev/null +++ b/libcxx/test/std/thread/thread.condition/thread.condition.condvar/wait_pred.pass.cpp @@ -0,0 +1,62 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <condition_variable> + +// class condition_variable; + +// template <class Predicate> +// void wait(unique_lock<mutex>& lock, Predicate pred); + +#include <condition_variable> +#include <mutex> +#include <thread> +#include <functional> +#include <cassert> + +std::condition_variable cv; +std::mutex mut; + +int test1 = 0; +int test2 = 0; + +class Pred +{ + int& i_; +public: + explicit Pred(int& i) : i_(i) {} + + bool operator()() {return i_ != 0;} +}; + +void f() +{ + std::unique_lock<std::mutex> lk(mut); + assert(test2 == 0); + test1 = 1; + cv.notify_one(); + cv.wait(lk, Pred(test2)); + assert(test2 != 0); +} + +int main() +{ + std::unique_lock<std::mutex>lk(mut); + std::thread t(f); + assert(test1 == 0); + while (test1 == 0) + cv.wait(lk); + assert(test1 != 0); + test2 = 1; + lk.unlock(); + cv.notify_one(); + t.join(); +} diff --git a/libcxx/test/std/thread/thread.condition/thread.condition.condvar/wait_until.pass.cpp b/libcxx/test/std/thread/thread.condition/thread.condition.condvar/wait_until.pass.cpp new file mode 100644 index 00000000000..d87a188e93d --- /dev/null +++ b/libcxx/test/std/thread/thread.condition/thread.condition.condvar/wait_until.pass.cpp @@ -0,0 +1,102 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <condition_variable> + +// class condition_variable; + +// template <class Clock, class Duration> +// cv_status +// wait_until(unique_lock<mutex>& lock, +// const chrono::time_point<Clock, Duration>& abs_time); + +#include <condition_variable> +#include <mutex> +#include <thread> +#include <chrono> +#include <cassert> + +struct Clock +{ + typedef std::chrono::milliseconds duration; + typedef duration::rep rep; + typedef duration::period period; + typedef std::chrono::time_point<Clock> time_point; + static const bool is_steady = true; + + static time_point now() + { + using namespace std::chrono; + return time_point(duration_cast<duration>( + steady_clock::now().time_since_epoch() + )); + } +}; + +std::condition_variable cv; +std::mutex mut; + +int test1 = 0; +int test2 = 0; + +int runs = 0; + +void f() +{ + std::unique_lock<std::mutex> lk(mut); + assert(test2 == 0); + test1 = 1; + cv.notify_one(); + Clock::time_point t0 = Clock::now(); + Clock::time_point t = t0 + Clock::duration(250); + while (test2 == 0 && cv.wait_until(lk, t) == std::cv_status::no_timeout) + ; + Clock::time_point t1 = Clock::now(); + if (runs == 0) + { + assert(t1 - t0 < Clock::duration(250)); + assert(test2 != 0); + } + else + { + assert(t1 - t0 - Clock::duration(250) < Clock::duration(50)); + assert(test2 == 0); + } + ++runs; +} + +int main() +{ + { + std::unique_lock<std::mutex>lk(mut); + std::thread t(f); + assert(test1 == 0); + while (test1 == 0) + cv.wait(lk); + assert(test1 != 0); + test2 = 1; + lk.unlock(); + cv.notify_one(); + t.join(); + } + test1 = 0; + test2 = 0; + { + std::unique_lock<std::mutex>lk(mut); + std::thread t(f); + assert(test1 == 0); + while (test1 == 0) + cv.wait(lk); + assert(test1 != 0); + lk.unlock(); + t.join(); + } +} diff --git a/libcxx/test/std/thread/thread.condition/thread.condition.condvar/wait_until_pred.pass.cpp b/libcxx/test/std/thread/thread.condition/thread.condition.condvar/wait_until_pred.pass.cpp new file mode 100644 index 00000000000..90ffb1d0b29 --- /dev/null +++ b/libcxx/test/std/thread/thread.condition/thread.condition.condvar/wait_until_pred.pass.cpp @@ -0,0 +1,113 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <condition_variable> + +// class condition_variable; + +// template <class Clock, class Duration, class Predicate> +// bool +// wait_until(unique_lock<mutex>& lock, +// const chrono::time_point<Clock, Duration>& abs_time, +// Predicate pred); + +#include <condition_variable> +#include <mutex> +#include <thread> +#include <chrono> +#include <cassert> + +struct Clock +{ + typedef std::chrono::milliseconds duration; + typedef duration::rep rep; + typedef duration::period period; + typedef std::chrono::time_point<Clock> time_point; + static const bool is_steady = true; + + static time_point now() + { + using namespace std::chrono; + return time_point(duration_cast<duration>( + steady_clock::now().time_since_epoch() + )); + } +}; + +class Pred +{ + int& i_; +public: + explicit Pred(int& i) : i_(i) {} + + bool operator()() {return i_ != 0;} +}; + +std::condition_variable cv; +std::mutex mut; + +int test1 = 0; +int test2 = 0; + +int runs = 0; + +void f() +{ + std::unique_lock<std::mutex> lk(mut); + assert(test2 == 0); + test1 = 1; + cv.notify_one(); + Clock::time_point t0 = Clock::now(); + Clock::time_point t = t0 + Clock::duration(250); + bool r = cv.wait_until(lk, t, Pred(test2)); + Clock::time_point t1 = Clock::now(); + if (runs == 0) + { + assert(t1 - t0 < Clock::duration(250)); + assert(test2 != 0); + assert(r); + } + else + { + assert(t1 - t0 - Clock::duration(250) < Clock::duration(50)); + assert(test2 == 0); + assert(!r); + } + ++runs; +} + +int main() +{ + { + std::unique_lock<std::mutex>lk(mut); + std::thread t(f); + assert(test1 == 0); + while (test1 == 0) + cv.wait(lk); + assert(test1 != 0); + test2 = 1; + lk.unlock(); + cv.notify_one(); + t.join(); + } + test1 = 0; + test2 = 0; + { + std::unique_lock<std::mutex>lk(mut); + std::thread t(f); + assert(test1 == 0); + while (test1 == 0) + cv.wait(lk); + assert(test1 != 0); + lk.unlock(); + t.join(); + } +} diff --git a/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/assign.fail.cpp b/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/assign.fail.cpp new file mode 100644 index 00000000000..0b8d8e965e6 --- /dev/null +++ b/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/assign.fail.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <condition_variable> + +// class condition_variable_any; + +// condition_variable_any& operator=(const condition_variable_any&) = delete; + +#include <condition_variable> +#include <cassert> + +int main() +{ + std::condition_variable_any cv0; + std::condition_variable_any cv1; + cv1 = cv0; +} diff --git a/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/copy.fail.cpp b/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/copy.fail.cpp new file mode 100644 index 00000000000..84902546d07 --- /dev/null +++ b/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/copy.fail.cpp @@ -0,0 +1,23 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <condition_variable> + +// class condition_variable_any; + +// condition_variable_any(const condition_variable_any&) = delete; + +#include <condition_variable> +#include <cassert> + +int main() +{ + std::condition_variable_any cv0; + std::condition_variable_any cv1(cv0); +} diff --git a/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/default.pass.cpp b/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/default.pass.cpp new file mode 100644 index 00000000000..210060a7461 --- /dev/null +++ b/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/default.pass.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <condition_variable> + +// class condition_variable_any; + +// condition_variable_any(); + +#include <condition_variable> +#include <cassert> + +int main() +{ + std::condition_variable_any cv; +} diff --git a/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/destructor.pass.cpp b/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/destructor.pass.cpp new file mode 100644 index 00000000000..6bdca7b010c --- /dev/null +++ b/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/destructor.pass.cpp @@ -0,0 +1,59 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <condition_variable> + +// class condition_variable_any; + +// ~condition_variable_any(); + +#include <condition_variable> +#include <mutex> +#include <thread> +#include <cassert> + +std::condition_variable_any* cv; +std::mutex m; + +bool f_ready = false; +bool g_ready = false; + +void f() +{ + m.lock(); + f_ready = true; + cv->notify_one(); + delete cv; + m.unlock(); +} + +void g() +{ + m.lock(); + g_ready = true; + cv->notify_one(); + while (!f_ready) + cv->wait(m); + m.unlock(); +} + +int main() +{ + cv = new std::condition_variable_any; + std::thread th2(g); + m.lock(); + while (!g_ready) + cv->wait(m); + m.unlock(); + std::thread th1(f); + th1.join(); + th2.join(); +} diff --git a/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/notify_all.pass.cpp b/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/notify_all.pass.cpp new file mode 100644 index 00000000000..27ead95682a --- /dev/null +++ b/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/notify_all.pass.cpp @@ -0,0 +1,73 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <condition_variable> + +// class condition_variable_any; + +// void notify_all(); + +#include <condition_variable> +#include <mutex> +#include <thread> +#include <cassert> + +std::condition_variable_any cv; + +typedef std::timed_mutex L0; +typedef std::unique_lock<L0> L1; + +L0 m0; + +int test0 = 0; +int test1 = 0; +int test2 = 0; + +void f1() +{ + L1 lk(m0); + assert(test1 == 0); + while (test1 == 0) + cv.wait(lk); + assert(test1 == 1); + test1 = 2; +} + +void f2() +{ + L1 lk(m0); + assert(test2 == 0); + while (test2 == 0) + cv.wait(lk); + assert(test2 == 1); + test2 = 2; +} + +int main() +{ + std::thread t1(f1); + std::thread t2(f2); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + { + L1 lk(m0); + test1 = 1; + test2 = 1; + } + cv.notify_all(); + { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + L1 lk(m0); + } + t1.join(); + t2.join(); + assert(test1 == 2); + assert(test2 == 2); +} diff --git a/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/notify_one.pass.cpp b/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/notify_one.pass.cpp new file mode 100644 index 00000000000..98f6c432c97 --- /dev/null +++ b/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/notify_one.pass.cpp @@ -0,0 +1,98 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <condition_variable> + +// class condition_variable_any; + +// void notify_one(); + +#include <condition_variable> +#include <mutex> +#include <thread> +#include <cassert> + +std::condition_variable_any cv; + +typedef std::timed_mutex L0; +typedef std::unique_lock<L0> L1; + +L0 m0; + +int test0 = 0; +int test1 = 0; +int test2 = 0; + +void f1() +{ + L1 lk(m0); + assert(test1 == 0); + while (test1 == 0) + cv.wait(lk); + assert(test1 == 1); + test1 = 2; +} + +void f2() +{ + L1 lk(m0); + assert(test2 == 0); + while (test2 == 0) + cv.wait(lk); + assert(test2 == 1); + test2 = 2; +} + +int main() +{ + std::thread t1(f1); + std::thread t2(f2); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + { + L1 lk(m0); + test1 = 1; + test2 = 1; + } + cv.notify_one(); + { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + L1 lk(m0); + } + if (test1 == 2) + { + t1.join(); + test1 = 0; + } + else if (test2 == 2) + { + t2.join(); + test2 = 0; + } + else + assert(false); + cv.notify_one(); + { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + L1 lk(m0); + } + if (test1 == 2) + { + t1.join(); + test1 = 0; + } + else if (test2 == 2) + { + t2.join(); + test2 = 0; + } + else + assert(false); +} diff --git a/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/wait.exception.pass.cpp b/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/wait.exception.pass.cpp new file mode 100644 index 00000000000..522c61b02d1 --- /dev/null +++ b/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/wait.exception.pass.cpp @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +#include <thread> +#include <condition_variable> +#include <mutex> +#include <chrono> +#include <iostream> +#include <cassert> + +void f1() +{ + std::exit(0); +} + +struct Mutex +{ + unsigned state = 0; + Mutex() = default; + ~Mutex() = default; + Mutex(const Mutex&) = delete; + Mutex& operator=(const Mutex&) = delete; + + void lock() + { + if (++state == 2) + throw 1; // this throw should end up calling terminate() + } + + void unlock() {} +}; + +Mutex mut; +std::condition_variable_any cv; + +void +signal_me() +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + cv.notify_one(); +} + +int +main() +{ + std::set_terminate(f1); + try + { + std::thread(signal_me).detach(); + mut.lock(); + cv.wait(mut); + } + catch (...) {} + assert(false); +} diff --git a/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/wait.pass.cpp b/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/wait.pass.cpp new file mode 100644 index 00000000000..f5c8926e34b --- /dev/null +++ b/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/wait.pass.cpp @@ -0,0 +1,57 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <condition_variable> + +// class condition_variable_any; + +// template <class Lock> +// void wait(Lock& lock); + +#include <condition_variable> +#include <mutex> +#include <thread> +#include <cassert> + +std::condition_variable_any cv; + +typedef std::timed_mutex L0; +typedef std::unique_lock<L0> L1; + +L0 m0; + +int test1 = 0; +int test2 = 0; + +void f() +{ + L1 lk(m0); + assert(test2 == 0); + test1 = 1; + cv.notify_one(); + while (test2 == 0) + cv.wait(lk); + assert(test2 != 0); +} + +int main() +{ + L1 lk(m0); + std::thread t(f); + assert(test1 == 0); + while (test1 == 0) + cv.wait(lk); + assert(test1 != 0); + test2 = 1; + lk.unlock(); + cv.notify_one(); + t.join(); +} diff --git a/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/wait_for.exception.pass.cpp b/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/wait_for.exception.pass.cpp new file mode 100644 index 00000000000..1906b589250 --- /dev/null +++ b/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/wait_for.exception.pass.cpp @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +#include <thread> +#include <condition_variable> +#include <mutex> +#include <chrono> +#include <iostream> +#include <cassert> + +void f1() +{ + std::exit(0); +} + +struct Mutex +{ + unsigned state = 0; + Mutex() = default; + ~Mutex() = default; + Mutex(const Mutex&) = delete; + Mutex& operator=(const Mutex&) = delete; + + void lock() + { + if (++state == 2) + throw 1; // this throw should end up calling terminate() + } + + void unlock() {} +}; + +Mutex mut; +std::condition_variable_any cv; + +void +signal_me() +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + cv.notify_one(); +} + +int +main() +{ + std::set_terminate(f1); + try + { + std::thread(signal_me).detach(); + mut.lock(); + cv.wait_for(mut, std::chrono::milliseconds(250)); + } + catch (...) {} + assert(false); +} diff --git a/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/wait_for.pass.cpp b/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/wait_for.pass.cpp new file mode 100644 index 00000000000..a4b4ed991f2 --- /dev/null +++ b/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/wait_for.pass.cpp @@ -0,0 +1,90 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <condition_variable> + +// class condition_variable_any; + +// template <class Lock, class Rep, class Period> +// cv_status +// wait_for(Lock& lock, const chrono::duration<Rep, Period>& rel_time); + +#include <condition_variable> +#include <mutex> +#include <thread> +#include <chrono> +#include <cassert> + +std::condition_variable_any cv; + +typedef std::timed_mutex L0; +typedef std::unique_lock<L0> L1; + +L0 m0; + +int test1 = 0; +int test2 = 0; + +int runs = 0; + +void f() +{ + typedef std::chrono::system_clock Clock; + typedef std::chrono::milliseconds milliseconds; + L1 lk(m0); + assert(test2 == 0); + test1 = 1; + cv.notify_one(); + Clock::time_point t0 = Clock::now(); + while (test2 == 0 && + cv.wait_for(lk, milliseconds(250)) == std::cv_status::no_timeout) + ; + Clock::time_point t1 = Clock::now(); + if (runs == 0) + { + assert(t1 - t0 < milliseconds(250)); + assert(test2 != 0); + } + else + { + assert(t1 - t0 - milliseconds(250) < milliseconds(50)); + assert(test2 == 0); + } + ++runs; +} + +int main() +{ + { + L1 lk(m0); + std::thread t(f); + assert(test1 == 0); + while (test1 == 0) + cv.wait(lk); + assert(test1 != 0); + test2 = 1; + lk.unlock(); + cv.notify_one(); + t.join(); + } + test1 = 0; + test2 = 0; + { + L1 lk(m0); + std::thread t(f); + assert(test1 == 0); + while (test1 == 0) + cv.wait(lk); + assert(test1 != 0); + lk.unlock(); + t.join(); + } +} diff --git a/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/wait_for_pred.pass.cpp b/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/wait_for_pred.pass.cpp new file mode 100644 index 00000000000..b2403079275 --- /dev/null +++ b/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/wait_for_pred.pass.cpp @@ -0,0 +1,98 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <condition_variable> + +// class condition_variable_any; + +// template <class Lock, class Rep, class Period, class Predicate> +// bool +// wait_for(Lock& lock, const chrono::duration<Rep, Period>& rel_time, +// Predicate pred); + +#include <condition_variable> +#include <mutex> +#include <thread> +#include <chrono> +#include <cassert> + +class Pred +{ + int& i_; +public: + explicit Pred(int& i) : i_(i) {} + + bool operator()() {return i_ != 0;} +}; + +std::condition_variable_any cv; + +typedef std::timed_mutex L0; +typedef std::unique_lock<L0> L1; + +L0 m0; + +int test1 = 0; +int test2 = 0; + +int runs = 0; + +void f() +{ + typedef std::chrono::system_clock Clock; + typedef std::chrono::milliseconds milliseconds; + L1 lk(m0); + assert(test2 == 0); + test1 = 1; + cv.notify_one(); + Clock::time_point t0 = Clock::now(); + bool r = cv.wait_for(lk, milliseconds(250), Pred(test2)); + Clock::time_point t1 = Clock::now(); + if (runs == 0) + { + assert(t1 - t0 < milliseconds(250)); + assert(test2 != 0); + } + else + { + assert(t1 - t0 - milliseconds(250) < milliseconds(50)); + assert(test2 == 0); + } + ++runs; +} + +int main() +{ + { + L1 lk(m0); + std::thread t(f); + assert(test1 == 0); + while (test1 == 0) + cv.wait(lk); + assert(test1 != 0); + test2 = 1; + lk.unlock(); + cv.notify_one(); + t.join(); + } + test1 = 0; + test2 = 0; + { + L1 lk(m0); + std::thread t(f); + assert(test1 == 0); + while (test1 == 0) + cv.wait(lk); + assert(test1 != 0); + lk.unlock(); + t.join(); + } +} diff --git a/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/wait_pred.pass.cpp b/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/wait_pred.pass.cpp new file mode 100644 index 00000000000..921ad69f145 --- /dev/null +++ b/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/wait_pred.pass.cpp @@ -0,0 +1,66 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <condition_variable> + +// class condition_variable_any; + +// template <class Lock, class Predicate> +// void wait(Lock& lock, Predicate pred); + +#include <condition_variable> +#include <mutex> +#include <thread> +#include <functional> +#include <cassert> + +std::condition_variable_any cv; + +typedef std::timed_mutex L0; +typedef std::unique_lock<L0> L1; + +L0 m0; + +int test1 = 0; +int test2 = 0; + +class Pred +{ + int& i_; +public: + explicit Pred(int& i) : i_(i) {} + + bool operator()() {return i_ != 0;} +}; + +void f() +{ + L1 lk(m0); + assert(test2 == 0); + test1 = 1; + cv.notify_one(); + cv.wait(lk, Pred(test2)); + assert(test2 != 0); +} + +int main() +{ + L1 lk(m0); + std::thread t(f); + assert(test1 == 0); + while (test1 == 0) + cv.wait(lk); + assert(test1 != 0); + test2 = 1; + lk.unlock(); + cv.notify_one(); + t.join(); +} diff --git a/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/wait_until.pass.cpp b/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/wait_until.pass.cpp new file mode 100644 index 00000000000..1994ebdfe60 --- /dev/null +++ b/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/wait_until.pass.cpp @@ -0,0 +1,105 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <condition_variable> + +// class condition_variable_any; + +// template <class Lock, class Clock, class Duration> +// cv_status +// wait_until(Lock& lock, const chrono::time_point<Clock, Duration>& abs_time); + +#include <condition_variable> +#include <mutex> +#include <thread> +#include <chrono> +#include <cassert> + +struct Clock +{ + typedef std::chrono::milliseconds duration; + typedef duration::rep rep; + typedef duration::period period; + typedef std::chrono::time_point<Clock> time_point; + static const bool is_steady = true; + + static time_point now() + { + using namespace std::chrono; + return time_point(duration_cast<duration>( + steady_clock::now().time_since_epoch() + )); + } +}; + +std::condition_variable_any cv; + +typedef std::timed_mutex L0; +typedef std::unique_lock<L0> L1; + +L0 m0; + +int test1 = 0; +int test2 = 0; + +int runs = 0; + +void f() +{ + L1 lk(m0); + assert(test2 == 0); + test1 = 1; + cv.notify_one(); + Clock::time_point t0 = Clock::now(); + Clock::time_point t = t0 + Clock::duration(250); + while (test2 == 0 && cv.wait_until(lk, t) == std::cv_status::no_timeout) + ; + Clock::time_point t1 = Clock::now(); + if (runs == 0) + { + assert(t1 - t0 < Clock::duration(250)); + assert(test2 != 0); + } + else + { + assert(t1 - t0 - Clock::duration(250) < Clock::duration(50)); + assert(test2 == 0); + } + ++runs; +} + +int main() +{ + { + L1 lk(m0); + std::thread t(f); + assert(test1 == 0); + while (test1 == 0) + cv.wait(lk); + assert(test1 != 0); + test2 = 1; + lk.unlock(); + cv.notify_one(); + t.join(); + } + test1 = 0; + test2 = 0; + { + L1 lk(m0); + std::thread t(f); + assert(test1 == 0); + while (test1 == 0) + cv.wait(lk); + assert(test1 != 0); + lk.unlock(); + t.join(); + } +} diff --git a/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/wait_until_pred.pass.cpp b/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/wait_until_pred.pass.cpp new file mode 100644 index 00000000000..c0fea0355b9 --- /dev/null +++ b/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/wait_until_pred.pass.cpp @@ -0,0 +1,117 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <condition_variable> + +// class condition_variable_any; + +// template <class Lock, class Duration, class Predicate> +// bool +// wait_until(Lock& lock, +// const chrono::time_point<Clock, Duration>& abs_time, +// Predicate pred); + +#include <condition_variable> +#include <mutex> +#include <thread> +#include <chrono> +#include <cassert> + +struct Clock +{ + typedef std::chrono::milliseconds duration; + typedef duration::rep rep; + typedef duration::period period; + typedef std::chrono::time_point<Clock> time_point; + static const bool is_steady = true; + + static time_point now() + { + using namespace std::chrono; + return time_point(duration_cast<duration>( + steady_clock::now().time_since_epoch() + )); + } +}; + +class Pred +{ + int& i_; +public: + explicit Pred(int& i) : i_(i) {} + + bool operator()() {return i_ != 0;} +}; + +std::condition_variable_any cv; + +typedef std::timed_mutex L0; +typedef std::unique_lock<L0> L1; + +L0 m0; + +int test1 = 0; +int test2 = 0; + +int runs = 0; + +void f() +{ + L1 lk(m0); + assert(test2 == 0); + test1 = 1; + cv.notify_one(); + Clock::time_point t0 = Clock::now(); + Clock::time_point t = t0 + Clock::duration(250); + bool r = cv.wait_until(lk, t, Pred(test2)); + Clock::time_point t1 = Clock::now(); + if (runs == 0) + { + assert(t1 - t0 < Clock::duration(250)); + assert(test2 != 0); + assert(r); + } + else + { + assert(t1 - t0 - Clock::duration(250) < Clock::duration(50)); + assert(test2 == 0); + assert(!r); + } + ++runs; +} + +int main() +{ + { + L1 lk(m0); + std::thread t(f); + assert(test1 == 0); + while (test1 == 0) + cv.wait(lk); + assert(test1 != 0); + test2 = 1; + lk.unlock(); + cv.notify_one(); + t.join(); + } + test1 = 0; + test2 = 0; + { + L1 lk(m0); + std::thread t(f); + assert(test1 == 0); + while (test1 == 0) + cv.wait(lk); + assert(test1 != 0); + lk.unlock(); + t.join(); + } +} diff --git a/libcxx/test/std/thread/thread.condition/version.pass.cpp b/libcxx/test/std/thread/thread.condition/version.pass.cpp new file mode 100644 index 00000000000..12a775e8339 --- /dev/null +++ b/libcxx/test/std/thread/thread.condition/version.pass.cpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <condition_variable> + +#include <condition_variable> + +#ifndef _LIBCPP_VERSION +#error _LIBCPP_VERSION not defined +#endif + +int main() +{ +} |