summaryrefslogtreecommitdiffstats
path: root/libcxx/test/thread/thread.condition/thread.condition.condvar
diff options
context:
space:
mode:
Diffstat (limited to 'libcxx/test/thread/thread.condition/thread.condition.condvar')
-rw-r--r--libcxx/test/thread/thread.condition/thread.condition.condvar/assign.fail.cpp24
-rw-r--r--libcxx/test/thread/thread.condition/thread.condition.condvar/copy.fail.cpp23
-rw-r--r--libcxx/test/thread/thread.condition/thread.condition.condvar/default.pass.cpp22
-rw-r--r--libcxx/test/thread/thread.condition/thread.condition.condvar/destructor.pass.cpp56
-rw-r--r--libcxx/test/thread/thread.condition/thread.condition.condvar/native_handle.pass.cpp27
-rw-r--r--libcxx/test/thread/thread.condition/thread.condition.condvar/notify_all.pass.cpp67
-rw-r--r--libcxx/test/thread/thread.condition/thread.condition.condvar/notify_one.pass.cpp92
-rw-r--r--libcxx/test/thread/thread.condition/thread.condition.condvar/wait.pass.cpp50
-rw-r--r--libcxx/test/thread/thread.condition/thread.condition.condvar/wait_for.pass.cpp85
-rw-r--r--libcxx/test/thread/thread.condition/thread.condition.condvar/wait_for_pred.pass.cpp93
-rw-r--r--libcxx/test/thread/thread.condition/thread.condition.condvar/wait_pred.pass.cpp60
-rw-r--r--libcxx/test/thread/thread.condition/thread.condition.condvar/wait_until.pass.cpp100
-rw-r--r--libcxx/test/thread/thread.condition/thread.condition.condvar/wait_until_pred.pass.cpp111
13 files changed, 810 insertions, 0 deletions
diff --git a/libcxx/test/thread/thread.condition/thread.condition.condvar/assign.fail.cpp b/libcxx/test/thread/thread.condition/thread.condition.condvar/assign.fail.cpp
new file mode 100644
index 00000000000..4d8d6d633bc
--- /dev/null
+++ b/libcxx/test/thread/thread.condition/thread.condition.condvar/assign.fail.cpp
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+// ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚThe LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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/thread/thread.condition/thread.condition.condvar/copy.fail.cpp b/libcxx/test/thread/thread.condition/thread.condition.condvar/copy.fail.cpp
new file mode 100644
index 00000000000..c302d6ae129
--- /dev/null
+++ b/libcxx/test/thread/thread.condition/thread.condition.condvar/copy.fail.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚThe LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. 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/thread/thread.condition/thread.condition.condvar/default.pass.cpp b/libcxx/test/thread/thread.condition/thread.condition.condvar/default.pass.cpp
new file mode 100644
index 00000000000..71cb83068df
--- /dev/null
+++ b/libcxx/test/thread/thread.condition/thread.condition.condvar/default.pass.cpp
@@ -0,0 +1,22 @@
+//===----------------------------------------------------------------------===//
+//
+// ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚThe LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <condition_variable>
+
+// class condition_variable;
+
+// condition_variable();
+
+#include <condition_variable>
+#include <cassert>
+
+int main()
+{
+ std::condition_variable cv;
+}
diff --git a/libcxx/test/thread/thread.condition/thread.condition.condvar/destructor.pass.cpp b/libcxx/test/thread/thread.condition/thread.condition.condvar/destructor.pass.cpp
new file mode 100644
index 00000000000..72382adf5c4
--- /dev/null
+++ b/libcxx/test/thread/thread.condition/thread.condition.condvar/destructor.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚThe LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <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/thread/thread.condition/thread.condition.condvar/native_handle.pass.cpp b/libcxx/test/thread/thread.condition/thread.condition.condvar/native_handle.pass.cpp
new file mode 100644
index 00000000000..e73ca3c6e4e
--- /dev/null
+++ b/libcxx/test/thread/thread.condition/thread.condition.condvar/native_handle.pass.cpp
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚThe LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <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/thread/thread.condition/thread.condition.condvar/notify_all.pass.cpp b/libcxx/test/thread/thread.condition/thread.condition.condvar/notify_all.pass.cpp
new file mode 100644
index 00000000000..a652f2a1d06
--- /dev/null
+++ b/libcxx/test/thread/thread.condition/thread.condition.condvar/notify_all.pass.cpp
@@ -0,0 +1,67 @@
+//===----------------------------------------------------------------------===//
+//
+// ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚThe LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <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/thread/thread.condition/thread.condition.condvar/notify_one.pass.cpp b/libcxx/test/thread/thread.condition/thread.condition.condvar/notify_one.pass.cpp
new file mode 100644
index 00000000000..55c70733cae
--- /dev/null
+++ b/libcxx/test/thread/thread.condition/thread.condition.condvar/notify_one.pass.cpp
@@ -0,0 +1,92 @@
+//===----------------------------------------------------------------------===//
+//
+// ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚThe LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <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/thread/thread.condition/thread.condition.condvar/wait.pass.cpp b/libcxx/test/thread/thread.condition/thread.condition.condvar/wait.pass.cpp
new file mode 100644
index 00000000000..793278dd026
--- /dev/null
+++ b/libcxx/test/thread/thread.condition/thread.condition.condvar/wait.pass.cpp
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚThe LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <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/thread/thread.condition/thread.condition.condvar/wait_for.pass.cpp b/libcxx/test/thread/thread.condition/thread.condition.condvar/wait_for.pass.cpp
new file mode 100644
index 00000000000..ebe85107b56
--- /dev/null
+++ b/libcxx/test/thread/thread.condition/thread.condition.condvar/wait_for.pass.cpp
@@ -0,0 +1,85 @@
+//===----------------------------------------------------------------------===//
+//
+// ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚThe LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <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(5));
+ 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/thread/thread.condition/thread.condition.condvar/wait_for_pred.pass.cpp b/libcxx/test/thread/thread.condition/thread.condition.condvar/wait_for_pred.pass.cpp
new file mode 100644
index 00000000000..d2cf6152a32
--- /dev/null
+++ b/libcxx/test/thread/thread.condition/thread.condition.condvar/wait_for_pred.pass.cpp
@@ -0,0 +1,93 @@
+//===----------------------------------------------------------------------===//
+//
+// ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚThe LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <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(2));
+ 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/thread/thread.condition/thread.condition.condvar/wait_pred.pass.cpp b/libcxx/test/thread/thread.condition/thread.condition.condvar/wait_pred.pass.cpp
new file mode 100644
index 00000000000..7aea96f8d3b
--- /dev/null
+++ b/libcxx/test/thread/thread.condition/thread.condition.condvar/wait_pred.pass.cpp
@@ -0,0 +1,60 @@
+//===----------------------------------------------------------------------===//
+//
+// ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚThe LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <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/thread/thread.condition/thread.condition.condvar/wait_until.pass.cpp b/libcxx/test/thread/thread.condition/thread.condition.condvar/wait_until.pass.cpp
new file mode 100644
index 00000000000..921891d3f39
--- /dev/null
+++ b/libcxx/test/thread/thread.condition/thread.condition.condvar/wait_until.pass.cpp
@@ -0,0 +1,100 @@
+//===----------------------------------------------------------------------===//
+//
+// ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚThe LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <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_monotonic = true;
+
+ static time_point now()
+ {
+ using namespace std::chrono;
+ return time_point(duration_cast<duration>(
+ monotonic_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(5));
+ 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/thread/thread.condition/thread.condition.condvar/wait_until_pred.pass.cpp b/libcxx/test/thread/thread.condition/thread.condition.condvar/wait_until_pred.pass.cpp
new file mode 100644
index 00000000000..0eb4825caad
--- /dev/null
+++ b/libcxx/test/thread/thread.condition/thread.condition.condvar/wait_until_pred.pass.cpp
@@ -0,0 +1,111 @@
+//===----------------------------------------------------------------------===//
+//
+// ΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚΚThe LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <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_monotonic = true;
+
+ static time_point now()
+ {
+ using namespace std::chrono;
+ return time_point(duration_cast<duration>(
+ monotonic_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(2));
+ 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();
+ }
+}
OpenPOWER on IntegriCloud