diff options
Diffstat (limited to 'test/std/thread')
262 files changed, 14344 insertions, 0 deletions
diff --git a/test/std/thread/futures/futures.async/async.pass.cpp b/test/std/thread/futures/futures.async/async.pass.cpp new file mode 100644 index 000000000000..c8a742566d8f --- /dev/null +++ b/test/std/thread/futures/futures.async/async.pass.cpp @@ -0,0 +1,198 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// template <class F, class... Args> +// future<typename result_of<F(Args...)>::type> +// async(F&& f, Args&&... args); + +// template <class F, class... Args> +// future<typename result_of<F(Args...)>::type> +// async(launch policy, F&& f, Args&&... args); + +#include <future> +#include <memory> +#include <cassert> + +typedef std::chrono::high_resolution_clock Clock; +typedef std::chrono::milliseconds ms; + +int f0() +{ + std::this_thread::sleep_for(ms(200)); + return 3; +} + +int i = 0; + +int& f1() +{ + std::this_thread::sleep_for(ms(200)); + return i; +} + +void f2() +{ + std::this_thread::sleep_for(ms(200)); +} + +std::unique_ptr<int> f3(int i) +{ + std::this_thread::sleep_for(ms(200)); + return std::unique_ptr<int>(new int(i)); +} + +std::unique_ptr<int> f4(std::unique_ptr<int>&& p) +{ + std::this_thread::sleep_for(ms(200)); + return std::move(p); +} + +void f5(int i) +{ + std::this_thread::sleep_for(ms(200)); + throw i; +} + +int main() +{ + { + std::future<int> f = std::async(f0); + std::this_thread::sleep_for(ms(300)); + Clock::time_point t0 = Clock::now(); + assert(f.get() == 3); + Clock::time_point t1 = Clock::now(); + assert(t1-t0 < ms(100)); + } + { + std::future<int> f = std::async(std::launch::async, f0); + std::this_thread::sleep_for(ms(300)); + Clock::time_point t0 = Clock::now(); + assert(f.get() == 3); + Clock::time_point t1 = Clock::now(); + assert(t1-t0 < ms(100)); + } + { + std::future<int> f = std::async(std::launch::any, f0); + std::this_thread::sleep_for(ms(300)); + Clock::time_point t0 = Clock::now(); + assert(f.get() == 3); + Clock::time_point t1 = Clock::now(); + assert(t1-t0 < ms(100)); + } + { + std::future<int> f = std::async(std::launch::deferred, f0); + std::this_thread::sleep_for(ms(300)); + Clock::time_point t0 = Clock::now(); + assert(f.get() == 3); + Clock::time_point t1 = Clock::now(); + assert(t1-t0 > ms(100)); + } + + { + std::future<int&> f = std::async(f1); + std::this_thread::sleep_for(ms(300)); + Clock::time_point t0 = Clock::now(); + assert(&f.get() == &i); + Clock::time_point t1 = Clock::now(); + assert(t1-t0 < ms(100)); + } + { + std::future<int&> f = std::async(std::launch::async, f1); + std::this_thread::sleep_for(ms(300)); + Clock::time_point t0 = Clock::now(); + assert(&f.get() == &i); + Clock::time_point t1 = Clock::now(); + assert(t1-t0 < ms(100)); + } + { + std::future<int&> f = std::async(std::launch::any, f1); + std::this_thread::sleep_for(ms(300)); + Clock::time_point t0 = Clock::now(); + assert(&f.get() == &i); + Clock::time_point t1 = Clock::now(); + assert(t1-t0 < ms(100)); + } + { + std::future<int&> f = std::async(std::launch::deferred, f1); + std::this_thread::sleep_for(ms(300)); + Clock::time_point t0 = Clock::now(); + assert(&f.get() == &i); + Clock::time_point t1 = Clock::now(); + assert(t1-t0 > ms(100)); + } + + { + std::future<void> f = std::async(f2); + std::this_thread::sleep_for(ms(300)); + Clock::time_point t0 = Clock::now(); + f.get(); + Clock::time_point t1 = Clock::now(); + assert(t1-t0 < ms(100)); + } + { + std::future<void> f = std::async(std::launch::async, f2); + std::this_thread::sleep_for(ms(300)); + Clock::time_point t0 = Clock::now(); + f.get(); + Clock::time_point t1 = Clock::now(); + assert(t1-t0 < ms(100)); + } + { + std::future<void> f = std::async(std::launch::any, f2); + std::this_thread::sleep_for(ms(300)); + Clock::time_point t0 = Clock::now(); + f.get(); + Clock::time_point t1 = Clock::now(); + assert(t1-t0 < ms(100)); + } + { + std::future<void> f = std::async(std::launch::deferred, f2); + std::this_thread::sleep_for(ms(300)); + Clock::time_point t0 = Clock::now(); + f.get(); + Clock::time_point t1 = Clock::now(); + assert(t1-t0 > ms(100)); + } + + { + std::future<std::unique_ptr<int>> f = std::async(f3, 3); + std::this_thread::sleep_for(ms(300)); + Clock::time_point t0 = Clock::now(); + assert(*f.get() == 3); + Clock::time_point t1 = Clock::now(); + assert(t1-t0 < ms(100)); + } + + { + std::future<std::unique_ptr<int>> f = + std::async(f4, std::unique_ptr<int>(new int(3))); + std::this_thread::sleep_for(ms(300)); + Clock::time_point t0 = Clock::now(); + assert(*f.get() == 3); + Clock::time_point t1 = Clock::now(); + assert(t1-t0 < ms(100)); + } + + { + std::future<void> f = std::async(f5, 3); + std::this_thread::sleep_for(ms(300)); + try { f.get(); assert (false); } catch ( int ex ) {} + } + + { + std::future<void> f = std::async(std::launch::deferred, f5, 3); + std::this_thread::sleep_for(ms(300)); + try { f.get(); assert (false); } catch ( int ex ) {} + } + +} diff --git a/test/std/thread/futures/futures.async/async_race.pass.cpp b/test/std/thread/futures/futures.async/async_race.pass.cpp new file mode 100644 index 000000000000..325a027132de --- /dev/null +++ b/test/std/thread/futures/futures.async/async_race.pass.cpp @@ -0,0 +1,67 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// template <class F, class... Args> +// future<typename result_of<F(Args...)>::type> +// async(F&& f, Args&&... args); + +// template <class F, class... Args> +// future<typename result_of<F(Args...)>::type> +// async(launch policy, F&& f, Args&&... args); + +// This test is designed to cause and allow TSAN to detect the race condition +// reported in PR23293. (http://llvm.org/PR23293). + +#include <future> +#include <chrono> +#include <thread> +#include <memory> +#include <cassert> + +int f_async() { + typedef std::chrono::milliseconds ms; + std::this_thread::sleep_for(ms(200)); + return 42; +} + +bool ran = false; + +int f_deferred() { + ran = true; + return 42; +} + +void test_each() { + { + std::future<int> f = std::async(f_async); + int const result = f.get(); + assert(result == 42); + } + { + std::future<int> f = std::async(std::launch::async, f_async); + int const result = f.get(); + assert(result == 42); + } + { + ran = false; + std::future<int> f = std::async(std::launch::deferred, f_deferred); + assert(ran == false); + int const result = f.get(); + assert(ran == true); + assert(result == 42); + } +} + +int main() { + for (int i=0; i < 25; ++i) test_each(); +} diff --git a/test/std/thread/futures/futures.errors/default_error_condition.pass.cpp b/test/std/thread/futures/futures.errors/default_error_condition.pass.cpp new file mode 100644 index 000000000000..7f28b8a23b81 --- /dev/null +++ b/test/std/thread/futures/futures.errors/default_error_condition.pass.cpp @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// const error_category& future_category(); + +// virtual error_condition default_error_condition(int ev) const; + +#include <future> +#include <cassert> + +int main() +{ + const std::error_category& e_cat = std::future_category(); + std::error_condition e_cond = e_cat.default_error_condition(static_cast<int>(std::errc::not_a_directory)); + assert(e_cond.category() == e_cat); + assert(e_cond.value() == static_cast<int>(std::errc::not_a_directory)); +} diff --git a/test/std/thread/futures/futures.errors/equivalent_error_code_int.pass.cpp b/test/std/thread/futures/futures.errors/equivalent_error_code_int.pass.cpp new file mode 100644 index 000000000000..cd0017657740 --- /dev/null +++ b/test/std/thread/futures/futures.errors/equivalent_error_code_int.pass.cpp @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// const error_category& future_category(); + +// virtual bool equivalent(const error_code& code, int condition) const; + +#include <future> +#include <cassert> + +int main() +{ + const std::error_category& e_cat = std::future_category(); + assert(e_cat.equivalent(std::error_code(5, e_cat), 5)); + assert(!e_cat.equivalent(std::error_code(5, e_cat), 6)); +} diff --git a/test/std/thread/futures/futures.errors/equivalent_int_error_condition.pass.cpp b/test/std/thread/futures/futures.errors/equivalent_int_error_condition.pass.cpp new file mode 100644 index 000000000000..05ad1ec9c6f5 --- /dev/null +++ b/test/std/thread/futures/futures.errors/equivalent_int_error_condition.pass.cpp @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// const error_category& future_category(); + +// virtual bool equivalent(int code, const error_condition& condition) const; + +#include <future> +#include <cassert> + +int main() +{ + const std::error_category& e_cat = std::future_category(); + std::error_condition e_cond = e_cat.default_error_condition(5); + assert(e_cat.equivalent(5, e_cond)); + assert(!e_cat.equivalent(6, e_cond)); +} diff --git a/test/std/thread/futures/futures.errors/future_category.pass.cpp b/test/std/thread/futures/futures.errors/future_category.pass.cpp new file mode 100644 index 000000000000..7f407a061d95 --- /dev/null +++ b/test/std/thread/futures/futures.errors/future_category.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 + +// <future> + +// const error_category& future_category(); + +#include <future> +#include <cstring> +#include <cassert> + +int main() +{ + const std::error_category& ec = std::future_category(); + assert(std::strcmp(ec.name(), "future") == 0); +} diff --git a/test/std/thread/futures/futures.errors/make_error_code.pass.cpp b/test/std/thread/futures/futures.errors/make_error_code.pass.cpp new file mode 100644 index 000000000000..3c14addf309f --- /dev/null +++ b/test/std/thread/futures/futures.errors/make_error_code.pass.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class error_code + +// error_code make_error_code(future_errc e); + +#include <future> +#include <cassert> + +int main() +{ + { + std::error_code ec = make_error_code(std::future_errc::broken_promise); + assert(ec.value() == static_cast<int>(std::future_errc::broken_promise)); + assert(ec.category() == std::future_category()); + } +} diff --git a/test/std/thread/futures/futures.errors/make_error_condition.pass.cpp b/test/std/thread/futures/futures.errors/make_error_condition.pass.cpp new file mode 100644 index 000000000000..52972aa373f5 --- /dev/null +++ b/test/std/thread/futures/futures.errors/make_error_condition.pass.cpp @@ -0,0 +1,30 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class error_condition + +// error_condition make_error_condition(future_errc e); + +#include <future> +#include <cassert> + +int main() +{ + { + const std::error_condition ec1 = + std::make_error_condition(std::future_errc::future_already_retrieved); + assert(ec1.value() == + static_cast<int>(std::future_errc::future_already_retrieved)); + assert(ec1.category() == std::future_category()); + } +} diff --git a/test/std/thread/futures/futures.future_error/code.pass.cpp b/test/std/thread/futures/futures.future_error/code.pass.cpp new file mode 100644 index 000000000000..e02af486fc39 --- /dev/null +++ b/test/std/thread/futures/futures.future_error/code.pass.cpp @@ -0,0 +1,43 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class future_error + +// const error_code& code() const throw(); + +#include <future> +#include <cassert> + +int main() +{ + { + std::error_code ec = std::make_error_code(std::future_errc::broken_promise); + std::future_error f(ec); + assert(f.code() == ec); + } + { + std::error_code ec = std::make_error_code(std::future_errc::future_already_retrieved); + std::future_error f(ec); + assert(f.code() == ec); + } + { + std::error_code ec = std::make_error_code(std::future_errc::promise_already_satisfied); + std::future_error f(ec); + assert(f.code() == ec); + } + { + std::error_code ec = std::make_error_code(std::future_errc::no_state); + std::future_error f(ec); + assert(f.code() == ec); + } +} diff --git a/test/std/thread/futures/futures.future_error/types.pass.cpp b/test/std/thread/futures/futures.future_error/types.pass.cpp new file mode 100644 index 000000000000..e741dd06e4b9 --- /dev/null +++ b/test/std/thread/futures/futures.future_error/types.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 + +// <future> + +// class future_error : public logic_error {...}; + +#include <future> +#include <type_traits> + +int main() +{ + static_assert((std::is_convertible<std::future_error*, + std::logic_error*>::value), ""); +} diff --git a/test/std/thread/futures/futures.future_error/what.pass.cpp b/test/std/thread/futures/futures.future_error/what.pass.cpp new file mode 100644 index 000000000000..52d2e944a684 --- /dev/null +++ b/test/std/thread/futures/futures.future_error/what.pass.cpp @@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// LWG 2056 changed the values of future_errc, so if we're using new headers +// with an old library we'll get incorrect messages. +// +// XFAIL: with_system_cxx_lib=x86_64-apple-darwin11 +// XFAIL: with_system_cxx_lib=x86_64-apple-darwin12 +// XFAIL: with_system_cxx_lib=x86_64-apple-darwin13 + +// <future> + +// class future_error + +// const char* what() const throw(); + +#include <future> +#include <cstring> +#include <cassert> + +int main() +{ + { + std::future_error f(std::make_error_code(std::future_errc::broken_promise)); + assert(std::strcmp(f.what(), "The associated promise has been destructed prior " + "to the associated state becoming ready.") == 0); + } + { + std::future_error f(std::make_error_code(std::future_errc::future_already_retrieved)); + assert(std::strcmp(f.what(), "The future has already been retrieved from " + "the promise or packaged_task.") == 0); + } + { + std::future_error f(std::make_error_code(std::future_errc::promise_already_satisfied)); + assert(std::strcmp(f.what(), "The state of the promise has already been set.") == 0); + } + { + std::future_error f(std::make_error_code(std::future_errc::no_state)); + assert(std::strcmp(f.what(), "Operation not permitted on an object without " + "an associated state.") == 0); + } +} diff --git a/test/std/thread/futures/futures.overview/future_errc.pass.cpp b/test/std/thread/futures/futures.overview/future_errc.pass.cpp new file mode 100644 index 000000000000..1e6fcb76a0e7 --- /dev/null +++ b/test/std/thread/futures/futures.overview/future_errc.pass.cpp @@ -0,0 +1,30 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// enum class future_errc +// { +// future_already_retrieved = 1, +// promise_already_satisfied, +// no_state +// broken_promise, +// }; + +#include <future> + +int main() +{ + static_assert(static_cast<int>(std::future_errc::future_already_retrieved) == 1, ""); + static_assert(static_cast<int>(std::future_errc::promise_already_satisfied) == 2, ""); + static_assert(static_cast<int>(std::future_errc::no_state) == 3, ""); + static_assert(static_cast<int>(std::future_errc::broken_promise) == 4, ""); +} diff --git a/test/std/thread/futures/futures.overview/future_status.pass.cpp b/test/std/thread/futures/futures.overview/future_status.pass.cpp new file mode 100644 index 000000000000..2c196aaac56d --- /dev/null +++ b/test/std/thread/futures/futures.overview/future_status.pass.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// enum class future_status +// { +// ready, +// timeout, +// deferred +// }; + +#include <future> + +int main() +{ + static_assert(static_cast<int>(std::future_status::ready) == 0, ""); + static_assert(static_cast<int>(std::future_status::timeout) == 1, ""); + static_assert(static_cast<int>(std::future_status::deferred) == 2, ""); +} diff --git a/test/std/thread/futures/futures.overview/is_error_code_enum_future_errc.pass.cpp b/test/std/thread/futures/futures.overview/is_error_code_enum_future_errc.pass.cpp new file mode 100644 index 000000000000..499de52598b6 --- /dev/null +++ b/test/std/thread/futures/futures.overview/is_error_code_enum_future_errc.pass.cpp @@ -0,0 +1,21 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// template <> struct is_error_code_enum<future_errc> : public true_type {}; + +#include <future> + +int main() +{ + static_assert(std::is_error_code_enum<std::future_errc>::value, ""); +} diff --git a/test/std/thread/futures/futures.overview/launch.pass.cpp b/test/std/thread/futures/futures.overview/launch.pass.cpp new file mode 100644 index 000000000000..da54f7ee6732 --- /dev/null +++ b/test/std/thread/futures/futures.overview/launch.pass.cpp @@ -0,0 +1,45 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// enum class launch +// { +// async = 1, +// deferred = 2, +// any = async | deferred +// }; + +#include <future> +#include <cassert> + +int main() +{ +#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS + static_assert(static_cast<int>(std::launch::any) == + (static_cast<int>(std::launch::async) | static_cast<int>(std::launch::deferred)), ""); +#else + static_assert(std::launch::any == (std::launch::async | std::launch::deferred), ""); + static_assert(std::launch(0) == (std::launch::async & std::launch::deferred), ""); + static_assert(std::launch::any == (std::launch::async ^ std::launch::deferred), ""); + static_assert(std::launch::deferred == ~std::launch::async, ""); + std::launch x = std::launch::async; + x &= std::launch::deferred; + assert(x == std::launch(0)); + x = std::launch::async; + x |= std::launch::deferred; + assert(x == std::launch::any); + x ^= std::launch::deferred; + assert(x == std::launch::async); +#endif + static_assert(static_cast<int>(std::launch::async) == 1, ""); + static_assert(static_cast<int>(std::launch::deferred) == 2, ""); +} diff --git a/test/std/thread/futures/futures.promise/alloc_ctor.pass.cpp b/test/std/thread/futures/futures.promise/alloc_ctor.pass.cpp new file mode 100644 index 000000000000..70a4e00b0d6a --- /dev/null +++ b/test/std/thread/futures/futures.promise/alloc_ctor.pass.cpp @@ -0,0 +1,84 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class promise<R> + +// template <class Allocator> +// promise(allocator_arg_t, const Allocator& a); + +#include <future> +#include <cassert> + +#include "../test_allocator.h" +#include "min_allocator.h" + +int main() +{ + assert(test_alloc_base::count == 0); + { + std::promise<int> p(std::allocator_arg, test_allocator<int>()); + assert(test_alloc_base::count == 1); + std::future<int> f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + } + assert(test_alloc_base::count == 0); + { + std::promise<int&> p(std::allocator_arg, test_allocator<int>()); + assert(test_alloc_base::count == 1); + std::future<int&> f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + } + assert(test_alloc_base::count == 0); + { + std::promise<void> p(std::allocator_arg, test_allocator<void>()); + assert(test_alloc_base::count == 1); + std::future<void> f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + } + assert(test_alloc_base::count == 0); + // Test with a minimal allocator + { + std::promise<int> p(std::allocator_arg, bare_allocator<void>()); + std::future<int> f = p.get_future(); + assert(f.valid()); + } + { + std::promise<int&> p(std::allocator_arg, bare_allocator<void>()); + std::future<int&> f = p.get_future(); + assert(f.valid()); + } + { + std::promise<void> p(std::allocator_arg, bare_allocator<void>()); + std::future<void> f = p.get_future(); + assert(f.valid()); + } + // Test with a minimal allocator that returns class-type pointers + { + std::promise<int> p(std::allocator_arg, min_allocator<void>()); + std::future<int> f = p.get_future(); + assert(f.valid()); + } + { + std::promise<int&> p(std::allocator_arg, min_allocator<void>()); + std::future<int&> f = p.get_future(); + assert(f.valid()); + } + { + std::promise<void> p(std::allocator_arg, min_allocator<void>()); + std::future<void> f = p.get_future(); + assert(f.valid()); + } +} diff --git a/test/std/thread/futures/futures.promise/copy_assign.fail.cpp b/test/std/thread/futures/futures.promise/copy_assign.fail.cpp new file mode 100644 index 000000000000..c08278122225 --- /dev/null +++ b/test/std/thread/futures/futures.promise/copy_assign.fail.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. +// +//===----------------------------------------------------------------------===// + +// <future> + +// class promise<R> + +// promise& operator=(const promise& rhs) = delete; + +#include <future> +#include <cassert> + +#include "../test_allocator.h" + +int main() +{ + assert(test_alloc_base::count == 0); + { + std::promise<int> p0(std::allocator_arg, test_allocator<int>()); + std::promise<int> p(std::allocator_arg, test_allocator<int>()); + assert(test_alloc_base::count == 2); + p = p0; + assert(test_alloc_base::count == 1); + std::future<int> f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + try + { + f = p0.get_future(); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::no_state)); + } + assert(test_alloc_base::count == 1); + } + assert(test_alloc_base::count == 0); + { + std::promise<int&> p0(std::allocator_arg, test_allocator<int>()); + std::promise<int&> p(std::allocator_arg, test_allocator<int>()); + assert(test_alloc_base::count == 2); + p = p0; + assert(test_alloc_base::count == 1); + std::future<int&> f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + try + { + f = p0.get_future(); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::no_state)); + } + assert(test_alloc_base::count == 1); + } + assert(test_alloc_base::count == 0); + { + std::promise<void> p0(std::allocator_arg, test_allocator<void>()); + std::promise<void> p(std::allocator_arg, test_allocator<void>()); + assert(test_alloc_base::count == 2); + p = p0; + assert(test_alloc_base::count == 1); + std::future<void> f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + try + { + f = p0.get_future(); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::no_state)); + } + assert(test_alloc_base::count == 1); + } + assert(test_alloc_base::count == 0); +} diff --git a/test/std/thread/futures/futures.promise/copy_ctor.fail.cpp b/test/std/thread/futures/futures.promise/copy_ctor.fail.cpp new file mode 100644 index 000000000000..36a3555aed46 --- /dev/null +++ b/test/std/thread/futures/futures.promise/copy_ctor.fail.cpp @@ -0,0 +1,81 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// <future> + +// class promise<R> + +// promise(const promise&) = delete; + +#include <future> +#include <cassert> + +#include "../test_allocator.h" + +int main() +{ + assert(test_alloc_base::count == 0); + { + std::promise<int> p0(std::allocator_arg, test_allocator<int>()); + std::promise<int> p(p0); + assert(test_alloc_base::count == 1); + std::future<int> f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + try + { + f = p0.get_future(); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::no_state)); + } + assert(test_alloc_base::count == 1); + } + assert(test_alloc_base::count == 0); + { + std::promise<int&> p0(std::allocator_arg, test_allocator<int>()); + std::promise<int&> p(p0); + assert(test_alloc_base::count == 1); + std::future<int&> f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + try + { + f = p0.get_future(); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::no_state)); + } + assert(test_alloc_base::count == 1); + } + assert(test_alloc_base::count == 0); + { + std::promise<void> p0(std::allocator_arg, test_allocator<void>()); + std::promise<void> p(p0); + assert(test_alloc_base::count == 1); + std::future<void> f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + try + { + f = p0.get_future(); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::no_state)); + } + assert(test_alloc_base::count == 1); + } + assert(test_alloc_base::count == 0); +} diff --git a/test/std/thread/futures/futures.promise/default.pass.cpp b/test/std/thread/futures/futures.promise/default.pass.cpp new file mode 100644 index 000000000000..95c9657c633e --- /dev/null +++ b/test/std/thread/futures/futures.promise/default.pass.cpp @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class promise<R> + +// promise(); + +#include <future> +#include <cassert> + +int main() +{ + { + std::promise<int> p; + std::future<int> f = p.get_future(); + assert(f.valid()); + } + { + std::promise<int&> p; + std::future<int&> f = p.get_future(); + assert(f.valid()); + } + { + std::promise<void> p; + std::future<void> f = p.get_future(); + assert(f.valid()); + } +} diff --git a/test/std/thread/futures/futures.promise/dtor.pass.cpp b/test/std/thread/futures/futures.promise/dtor.pass.cpp new file mode 100644 index 000000000000..78912f12adb9 --- /dev/null +++ b/test/std/thread/futures/futures.promise/dtor.pass.cpp @@ -0,0 +1,116 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class promise<R> + +// ~promise(); + +#include <future> +#include <cassert> + +int main() +{ + { + typedef int T; + std::future<T> f; + { + std::promise<T> p; + f = p.get_future(); + p.set_value(3); + } + assert(f.get() == 3); + } + { + typedef int T; + std::future<T> f; + { + std::promise<T> p; + f = p.get_future(); + } + try + { + T i = f.get(); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::broken_promise)); + } + } + + { + typedef int& T; + int i = 4; + std::future<T> f; + { + std::promise<T> p; + f = p.get_future(); + p.set_value(i); + } + assert(&f.get() == &i); + } + { + typedef int& T; + std::future<T> f; + { + std::promise<T> p; + f = p.get_future(); + } + try + { + T i = f.get(); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::broken_promise)); + } + } + + { + typedef void T; + std::future<T> f; + { + std::promise<T> p; + f = p.get_future(); + p.set_value(); + } + f.get(); + assert(true); + } + { + typedef void T; + std::future<T> f; + { + std::promise<T> p; + f = p.get_future(); + } + try + { + f.get(); + assert(false); + } + catch (const std::future_error& e) + { + // LWG 2056 changed the values of future_errc, so if we're using new + // headers with an old library the error codes won't line up. + // + // Note that this particular check only applies to promise<void> + // since the other specializations happen to be implemented in the + // header rather than the library. + assert( + e.code() == make_error_code(std::future_errc::broken_promise) || + e.code() == std::error_code(0, std::future_category())); + } + } +} diff --git a/test/std/thread/futures/futures.promise/get_future.pass.cpp b/test/std/thread/futures/futures.promise/get_future.pass.cpp new file mode 100644 index 000000000000..a7d084ee7873 --- /dev/null +++ b/test/std/thread/futures/futures.promise/get_future.pass.cpp @@ -0,0 +1,55 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class promise<R> + +// future<R> get_future(); + +#include <future> +#include <cassert> + +int main() +{ + { + std::promise<double> p; + std::future<double> f = p.get_future(); + p.set_value(105.5); + assert(f.get() == 105.5); + } + { + std::promise<double> p; + std::future<double> f = p.get_future(); + try + { + f = p.get_future(); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::future_already_retrieved)); + } + } + { + std::promise<double> p; + std::promise<double> p0 = std::move(p); + try + { + std::future<double> f = p.get_future(); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::no_state)); + } + } +} diff --git a/test/std/thread/futures/futures.promise/move_assign.pass.cpp b/test/std/thread/futures/futures.promise/move_assign.pass.cpp new file mode 100644 index 000000000000..c3097df74990 --- /dev/null +++ b/test/std/thread/futures/futures.promise/move_assign.pass.cpp @@ -0,0 +1,91 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class promise<R> + +// promise& operator=(promise&& rhs); + +#include <future> +#include <cassert> + +#include "../test_allocator.h" + +int main() +{ +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + assert(test_alloc_base::count == 0); + { + std::promise<int> p0(std::allocator_arg, test_allocator<int>()); + std::promise<int> p(std::allocator_arg, test_allocator<int>()); + assert(test_alloc_base::count == 2); + p = std::move(p0); + assert(test_alloc_base::count == 1); + std::future<int> f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + try + { + f = p0.get_future(); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::no_state)); + } + assert(test_alloc_base::count == 1); + } + assert(test_alloc_base::count == 0); + { + std::promise<int&> p0(std::allocator_arg, test_allocator<int>()); + std::promise<int&> p(std::allocator_arg, test_allocator<int>()); + assert(test_alloc_base::count == 2); + p = std::move(p0); + assert(test_alloc_base::count == 1); + std::future<int&> f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + try + { + f = p0.get_future(); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::no_state)); + } + assert(test_alloc_base::count == 1); + } + assert(test_alloc_base::count == 0); + { + std::promise<void> p0(std::allocator_arg, test_allocator<void>()); + std::promise<void> p(std::allocator_arg, test_allocator<void>()); + assert(test_alloc_base::count == 2); + p = std::move(p0); + assert(test_alloc_base::count == 1); + std::future<void> f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + try + { + f = p0.get_future(); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::no_state)); + } + assert(test_alloc_base::count == 1); + } + assert(test_alloc_base::count == 0); +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +} diff --git a/test/std/thread/futures/futures.promise/move_ctor.pass.cpp b/test/std/thread/futures/futures.promise/move_ctor.pass.cpp new file mode 100644 index 000000000000..eeec4fb15b95 --- /dev/null +++ b/test/std/thread/futures/futures.promise/move_ctor.pass.cpp @@ -0,0 +1,85 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class promise<R> + +// promise(promise&& rhs); + +#include <future> +#include <cassert> + +#include "../test_allocator.h" + +int main() +{ +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + assert(test_alloc_base::count == 0); + { + std::promise<int> p0(std::allocator_arg, test_allocator<int>()); + std::promise<int> p(std::move(p0)); + assert(test_alloc_base::count == 1); + std::future<int> f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + try + { + f = p0.get_future(); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::no_state)); + } + assert(test_alloc_base::count == 1); + } + assert(test_alloc_base::count == 0); + { + std::promise<int&> p0(std::allocator_arg, test_allocator<int>()); + std::promise<int&> p(std::move(p0)); + assert(test_alloc_base::count == 1); + std::future<int&> f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + try + { + f = p0.get_future(); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::no_state)); + } + assert(test_alloc_base::count == 1); + } + assert(test_alloc_base::count == 0); + { + std::promise<void> p0(std::allocator_arg, test_allocator<void>()); + std::promise<void> p(std::move(p0)); + assert(test_alloc_base::count == 1); + std::future<void> f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + try + { + f = p0.get_future(); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::no_state)); + } + assert(test_alloc_base::count == 1); + } + assert(test_alloc_base::count == 0); +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +} diff --git a/test/std/thread/futures/futures.promise/set_exception.pass.cpp b/test/std/thread/futures/futures.promise/set_exception.pass.cpp new file mode 100644 index 000000000000..51c05eb803cb --- /dev/null +++ b/test/std/thread/futures/futures.promise/set_exception.pass.cpp @@ -0,0 +1,47 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class promise<R> + +// void set_exception(exception_ptr p); + +#include <future> +#include <cassert> + +int main() +{ + { + typedef int T; + std::promise<T> p; + std::future<T> f = p.get_future(); + p.set_exception(std::make_exception_ptr(3)); + try + { + f.get(); + assert(false); + } + catch (int i) + { + assert(i == 3); + } + try + { + p.set_exception(std::make_exception_ptr(3)); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::promise_already_satisfied)); + } + } +} diff --git a/test/std/thread/futures/futures.promise/set_exception_at_thread_exit.pass.cpp b/test/std/thread/futures/futures.promise/set_exception_at_thread_exit.pass.cpp new file mode 100644 index 000000000000..5e57692563d8 --- /dev/null +++ b/test/std/thread/futures/futures.promise/set_exception_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 + +// <future> + +// class promise<R> + +// void promise::set_exception_at_thread_exit(exception_ptr p); + +#include <future> +#include <cassert> + +void func(std::promise<int> p) +{ + const int i = 5; + p.set_exception_at_thread_exit(std::make_exception_ptr(3)); +} + +int main() +{ + { + typedef int T; + std::promise<T> p; + std::future<T> f = p.get_future(); + std::thread(func, std::move(p)).detach(); + try + { + f.get(); + assert(false); + } + catch (int i) + { + assert(i == 3); + } + } +} diff --git a/test/std/thread/futures/futures.promise/set_lvalue.pass.cpp b/test/std/thread/futures/futures.promise/set_lvalue.pass.cpp new file mode 100644 index 000000000000..cdc37775012c --- /dev/null +++ b/test/std/thread/futures/futures.promise/set_lvalue.pass.cpp @@ -0,0 +1,43 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class promise<R> + +// void promise<R&>::set_value(R& r); + +#include <future> +#include <cassert> + +int main() +{ + { + typedef int& T; + int i = 3; + std::promise<T> p; + std::future<T> f = p.get_future(); + p.set_value(i); + int& j = f.get(); + assert(j == 3); + ++i; + assert(j == 4); + try + { + p.set_value(i); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::promise_already_satisfied)); + } + } +} diff --git a/test/std/thread/futures/futures.promise/set_lvalue_at_thread_exit.pass.cpp b/test/std/thread/futures/futures.promise/set_lvalue_at_thread_exit.pass.cpp new file mode 100644 index 000000000000..18f87c596a00 --- /dev/null +++ b/test/std/thread/futures/futures.promise/set_lvalue_at_thread_exit.pass.cpp @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class promise<R> + +// void promise<R&>::set_value_at_thread_exit(R& r); + +#include <future> +#include <memory> +#include <cassert> + +int i = 0; + +void func(std::promise<int&> p) +{ + p.set_value_at_thread_exit(i); + i = 4; +} + +int main() +{ + { + std::promise<int&> p; + std::future<int&> f = p.get_future(); + std::thread(func, std::move(p)).detach(); + assert(f.get() == 4); + } +} diff --git a/test/std/thread/futures/futures.promise/set_rvalue.pass.cpp b/test/std/thread/futures/futures.promise/set_rvalue.pass.cpp new file mode 100644 index 000000000000..dab4bf7e9c83 --- /dev/null +++ b/test/std/thread/futures/futures.promise/set_rvalue.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 + +// <future> + +// class promise<R> + +// void promise::set_value(R&& r); + +#include <future> +#include <memory> +#include <cassert> + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +struct A +{ + A() {} + A(const A&) = delete; + A(A&&) {throw 9;} +}; + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +int main() +{ +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + { + typedef std::unique_ptr<int> T; + T i(new int(3)); + std::promise<T> p; + std::future<T> f = p.get_future(); + p.set_value(std::move(i)); + assert(*f.get() == 3); + try + { + p.set_value(std::move(i)); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::promise_already_satisfied)); + } + } + { + typedef A T; + T i; + std::promise<T> p; + std::future<T> f = p.get_future(); + try + { + p.set_value(std::move(i)); + assert(false); + } + catch (int j) + { + assert(j == 9); + } + } +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +} diff --git a/test/std/thread/futures/futures.promise/set_rvalue_at_thread_exit.pass.cpp b/test/std/thread/futures/futures.promise/set_rvalue_at_thread_exit.pass.cpp new file mode 100644 index 000000000000..8f3b76865e2a --- /dev/null +++ b/test/std/thread/futures/futures.promise/set_rvalue_at_thread_exit.pass.cpp @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class promise<R> + +// void promise::set_value_at_thread_exit(R&& r); + +#include <future> +#include <memory> +#include <cassert> + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +void func(std::promise<std::unique_ptr<int>> p) +{ + p.set_value_at_thread_exit(std::unique_ptr<int>(new int(5))); +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +int main() +{ +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + { + std::promise<std::unique_ptr<int>> p; + std::future<std::unique_ptr<int>> f = p.get_future(); + std::thread(func, std::move(p)).detach(); + assert(*f.get() == 5); + } +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +} diff --git a/test/std/thread/futures/futures.promise/set_value_at_thread_exit_const.pass.cpp b/test/std/thread/futures/futures.promise/set_value_at_thread_exit_const.pass.cpp new file mode 100644 index 000000000000..ec50cc310298 --- /dev/null +++ b/test/std/thread/futures/futures.promise/set_value_at_thread_exit_const.pass.cpp @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class promise<R> + +// void promise::set_value_at_thread_exit(const R& r); + +#include <future> +#include <cassert> + +void func(std::promise<int> p) +{ + const int i = 5; + p.set_value_at_thread_exit(i); +} + +int main() +{ + { + std::promise<int> p; + std::future<int> f = p.get_future(); + std::thread(func, std::move(p)).detach(); + assert(f.get() == 5); + } +} diff --git a/test/std/thread/futures/futures.promise/set_value_at_thread_exit_void.pass.cpp b/test/std/thread/futures/futures.promise/set_value_at_thread_exit_void.pass.cpp new file mode 100644 index 000000000000..8c092084668d --- /dev/null +++ b/test/std/thread/futures/futures.promise/set_value_at_thread_exit_void.pass.cpp @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class promise<R> + +// void promise<void>::set_value_at_thread_exit(); + +#include <future> +#include <memory> +#include <cassert> + +int i = 0; + +void func(std::promise<void> p) +{ + p.set_value_at_thread_exit(); + i = 1; +} + +int main() +{ + { + std::promise<void> p; + std::future<void> f = p.get_future(); + std::thread(func, std::move(p)).detach(); + f.get(); + assert(i == 1); + } +} diff --git a/test/std/thread/futures/futures.promise/set_value_const.pass.cpp b/test/std/thread/futures/futures.promise/set_value_const.pass.cpp new file mode 100644 index 000000000000..6673f6307579 --- /dev/null +++ b/test/std/thread/futures/futures.promise/set_value_const.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 + +// <future> + +// class promise<R> + +// void promise::set_value(const R& r); + +#include <future> +#include <cassert> + +struct A +{ + A() {} + A(const A&) {throw 10;} +}; + +int main() +{ + { + typedef int T; + T i = 3; + std::promise<T> p; + std::future<T> f = p.get_future(); + p.set_value(i); + ++i; + assert(f.get() == 3); + --i; + try + { + p.set_value(i); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::promise_already_satisfied)); + } + } + { + typedef A T; + T i; + std::promise<T> p; + std::future<T> f = p.get_future(); + try + { + p.set_value(i); + assert(false); + } + catch (int j) + { + assert(j == 10); + } + } +} diff --git a/test/std/thread/futures/futures.promise/set_value_void.pass.cpp b/test/std/thread/futures/futures.promise/set_value_void.pass.cpp new file mode 100644 index 000000000000..5012e0bfe5fd --- /dev/null +++ b/test/std/thread/futures/futures.promise/set_value_void.pass.cpp @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class promise<R> + +// void promise<void>::set_value(); + +#include <future> +#include <cassert> + +int main() +{ + { + typedef void T; + std::promise<T> p; + std::future<T> f = p.get_future(); + p.set_value(); + f.get(); + try + { + p.set_value(); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::promise_already_satisfied)); + } + } +} diff --git a/test/std/thread/futures/futures.promise/swap.pass.cpp b/test/std/thread/futures/futures.promise/swap.pass.cpp new file mode 100644 index 000000000000..1ed3e646813c --- /dev/null +++ b/test/std/thread/futures/futures.promise/swap.pass.cpp @@ -0,0 +1,84 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class promise<R> + +// void swap(promise& other); + +// template <class R> void swap(promise<R>& x, promise<R>& y); + +#include <future> +#include <cassert> + +#include "../test_allocator.h" + +int main() +{ + assert(test_alloc_base::count == 0); + { + std::promise<int> p0(std::allocator_arg, test_allocator<int>()); + std::promise<int> p(std::allocator_arg, test_allocator<int>()); + assert(test_alloc_base::count == 2); + p.swap(p0); + assert(test_alloc_base::count == 2); + std::future<int> f = p.get_future(); + assert(test_alloc_base::count == 2); + assert(f.valid()); + f = p0.get_future(); + assert(f.valid()); + assert(test_alloc_base::count == 2); + } + assert(test_alloc_base::count == 0); + { + std::promise<int> p0(std::allocator_arg, test_allocator<int>()); + std::promise<int> p(std::allocator_arg, test_allocator<int>()); + assert(test_alloc_base::count == 2); + swap(p, p0); + assert(test_alloc_base::count == 2); + std::future<int> f = p.get_future(); + assert(test_alloc_base::count == 2); + assert(f.valid()); + f = p0.get_future(); + assert(f.valid()); + assert(test_alloc_base::count == 2); + } + assert(test_alloc_base::count == 0); + { + std::promise<int> p0(std::allocator_arg, test_allocator<int>()); + std::promise<int> p; + assert(test_alloc_base::count == 1); + p.swap(p0); + assert(test_alloc_base::count == 1); + std::future<int> f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + f = p0.get_future(); + assert(f.valid()); + assert(test_alloc_base::count == 1); + } + assert(test_alloc_base::count == 0); + { + std::promise<int> p0(std::allocator_arg, test_allocator<int>()); + std::promise<int> p; + assert(test_alloc_base::count == 1); + swap(p, p0); + assert(test_alloc_base::count == 1); + std::future<int> f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + f = p0.get_future(); + assert(f.valid()); + assert(test_alloc_base::count == 1); + } + assert(test_alloc_base::count == 0); +} diff --git a/test/std/thread/futures/futures.promise/uses_allocator.pass.cpp b/test/std/thread/futures/futures.promise/uses_allocator.pass.cpp new file mode 100644 index 000000000000..458826e956e1 --- /dev/null +++ b/test/std/thread/futures/futures.promise/uses_allocator.pass.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class promise<R> + +// template <class R, class Alloc> +// struct uses_allocator<promise<R>, Alloc> +// : true_type { }; + +#include <future> +#include "../test_allocator.h" + +int main() +{ + static_assert((std::uses_allocator<std::promise<int>, test_allocator<int> >::value), ""); + static_assert((std::uses_allocator<std::promise<int&>, test_allocator<int> >::value), ""); + static_assert((std::uses_allocator<std::promise<void>, test_allocator<void> >::value), ""); +} diff --git a/test/std/thread/futures/futures.shared_future/copy_assign.pass.cpp b/test/std/thread/futures/futures.shared_future/copy_assign.pass.cpp new file mode 100644 index 000000000000..b23ba196ec30 --- /dev/null +++ b/test/std/thread/futures/futures.shared_future/copy_assign.pass.cpp @@ -0,0 +1,76 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class shared_future<R> + +// shared_future& operator=(const shared_future& rhs); + +#include <future> +#include <cassert> + +int main() +{ +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + { + typedef int T; + std::promise<T> p; + std::shared_future<T> f0 = p.get_future(); + std::shared_future<T> f; + f = f0; + assert(f0.valid()); + assert(f.valid()); + } + { + typedef int T; + std::shared_future<T> f0; + std::shared_future<T> f; + f = f0; + assert(!f0.valid()); + assert(!f.valid()); + } + { + typedef int& T; + std::promise<T> p; + std::shared_future<T> f0 = p.get_future(); + std::shared_future<T> f; + f = f0; + assert(f0.valid()); + assert(f.valid()); + } + { + typedef int& T; + std::shared_future<T> f0; + std::shared_future<T> f; + f = f0; + assert(!f0.valid()); + assert(!f.valid()); + } + { + typedef void T; + std::promise<T> p; + std::shared_future<T> f0 = p.get_future(); + std::shared_future<T> f; + f = f0; + assert(f0.valid()); + assert(f.valid()); + } + { + typedef void T; + std::shared_future<T> f0; + std::shared_future<T> f; + f = f0; + assert(!f0.valid()); + assert(!f.valid()); + } +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +} diff --git a/test/std/thread/futures/futures.shared_future/copy_ctor.pass.cpp b/test/std/thread/futures/futures.shared_future/copy_ctor.pass.cpp new file mode 100644 index 000000000000..425d1f9be96f --- /dev/null +++ b/test/std/thread/futures/futures.shared_future/copy_ctor.pass.cpp @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class shared_future<R> + +// shared_future(const shared_future& rhs); + +#include <future> +#include <cassert> + +int main() +{ + { + typedef int T; + std::promise<T> p; + std::shared_future<T> f0 = p.get_future(); + std::shared_future<T> f = f0; + assert(f0.valid()); + assert(f.valid()); + } + { + typedef int T; + std::shared_future<T> f0; + std::shared_future<T> f = f0; + assert(!f0.valid()); + assert(!f.valid()); + } + { + typedef int& T; + std::promise<T> p; + std::shared_future<T> f0 = p.get_future(); + std::shared_future<T> f = f0; + assert(f0.valid()); + assert(f.valid()); + } + { + typedef int& T; + std::shared_future<T> f0; + std::shared_future<T> f = std::move(f0); + assert(!f0.valid()); + assert(!f.valid()); + } + { + typedef void T; + std::promise<T> p; + std::shared_future<T> f0 = p.get_future(); + std::shared_future<T> f = f0; + assert(f0.valid()); + assert(f.valid()); + } + { + typedef void T; + std::shared_future<T> f0; + std::shared_future<T> f = f0; + assert(!f0.valid()); + assert(!f.valid()); + } +} diff --git a/test/std/thread/futures/futures.shared_future/ctor_future.pass.cpp b/test/std/thread/futures/futures.shared_future/ctor_future.pass.cpp new file mode 100644 index 000000000000..3a78b80f0634 --- /dev/null +++ b/test/std/thread/futures/futures.shared_future/ctor_future.pass.cpp @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class shared_future<R> + +// shared_future(future<R>&& rhs); + +#include <future> +#include <cassert> + +int main() +{ + { + typedef int T; + std::promise<T> p; + std::future<T> f0 = p.get_future(); + std::shared_future<T> f = std::move(f0); + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef int T; + std::future<T> f0; + std::shared_future<T> f = std::move(f0); + assert(!f0.valid()); + assert(!f.valid()); + } + { + typedef int& T; + std::promise<T> p; + std::future<T> f0 = p.get_future(); + std::shared_future<T> f = std::move(f0); + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef int& T; + std::future<T> f0; + std::shared_future<T> f = std::move(f0); + assert(!f0.valid()); + assert(!f.valid()); + } + { + typedef void T; + std::promise<T> p; + std::future<T> f0 = p.get_future(); + std::shared_future<T> f = std::move(f0); + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef void T; + std::future<T> f0; + std::shared_future<T> f = std::move(f0); + assert(!f0.valid()); + assert(!f.valid()); + } +} diff --git a/test/std/thread/futures/futures.shared_future/default.pass.cpp b/test/std/thread/futures/futures.shared_future/default.pass.cpp new file mode 100644 index 000000000000..92927f5f6933 --- /dev/null +++ b/test/std/thread/futures/futures.shared_future/default.pass.cpp @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class shared_future<R> + +// shared_future(); + +#include <future> +#include <cassert> + +int main() +{ + { + std::shared_future<int> f; + assert(!f.valid()); + } + { + std::shared_future<int&> f; + assert(!f.valid()); + } + { + std::shared_future<void> f; + assert(!f.valid()); + } +} diff --git a/test/std/thread/futures/futures.shared_future/dtor.pass.cpp b/test/std/thread/futures/futures.shared_future/dtor.pass.cpp new file mode 100644 index 000000000000..baa89cb12b1c --- /dev/null +++ b/test/std/thread/futures/futures.shared_future/dtor.pass.cpp @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class shared_future<R> + +// ~shared_future(); + +#include <future> +#include <cassert> + +#include "../test_allocator.h" + +int main() +{ + assert(test_alloc_base::count == 0); + { + typedef int T; + std::shared_future<T> f; + { + std::promise<T> p(std::allocator_arg, test_allocator<T>()); + assert(test_alloc_base::count == 1); + f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + } + assert(test_alloc_base::count == 1); + assert(f.valid()); + } + assert(test_alloc_base::count == 0); + { + typedef int& T; + std::shared_future<T> f; + { + std::promise<T> p(std::allocator_arg, test_allocator<int>()); + assert(test_alloc_base::count == 1); + f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + } + assert(test_alloc_base::count == 1); + assert(f.valid()); + } + assert(test_alloc_base::count == 0); + { + typedef void T; + std::shared_future<T> f; + { + std::promise<T> p(std::allocator_arg, test_allocator<T>()); + assert(test_alloc_base::count == 1); + f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + } + assert(test_alloc_base::count == 1); + assert(f.valid()); + } + assert(test_alloc_base::count == 0); +} diff --git a/test/std/thread/futures/futures.shared_future/get.pass.cpp b/test/std/thread/futures/futures.shared_future/get.pass.cpp new file mode 100644 index 000000000000..c5ee234b127f --- /dev/null +++ b/test/std/thread/futures/futures.shared_future/get.pass.cpp @@ -0,0 +1,145 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class shared_future<R> + +// const R& shared_future::get(); +// R& shared_future<R&>::get(); +// void shared_future<void>::get(); + +#include <future> +#include <cassert> + +void func1(std::promise<int> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + p.set_value(3); +} + +void func2(std::promise<int> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + p.set_exception(std::make_exception_ptr(3)); +} + +int j = 0; + +void func3(std::promise<int&> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + j = 5; + p.set_value(j); +} + +void func4(std::promise<int&> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + p.set_exception(std::make_exception_ptr(3.5)); +} + +void func5(std::promise<void> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + p.set_value(); +} + +void func6(std::promise<void> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + p.set_exception(std::make_exception_ptr('c')); +} + +int main() +{ + { + typedef int T; + { + std::promise<T> p; + std::shared_future<T> f = p.get_future(); + std::thread(func1, std::move(p)).detach(); + assert(f.valid()); + assert(f.get() == 3); + assert(f.valid()); + } + { + std::promise<T> p; + std::shared_future<T> f = p.get_future(); + std::thread(func2, std::move(p)).detach(); + try + { + assert(f.valid()); + assert(f.get() == 3); + assert(false); + } + catch (int i) + { + assert(i == 3); + } + assert(f.valid()); + } + } + { + typedef int& T; + { + std::promise<T> p; + std::shared_future<T> f = p.get_future(); + std::thread(func3, std::move(p)).detach(); + assert(f.valid()); + assert(f.get() == 5); + assert(f.valid()); + } + { + std::promise<T> p; + std::shared_future<T> f = p.get_future(); + std::thread(func4, std::move(p)).detach(); + try + { + assert(f.valid()); + assert(f.get() == 3); + assert(false); + } + catch (double i) + { + assert(i == 3.5); + } + assert(f.valid()); + } + } + { + typedef void T; + { + std::promise<T> p; + std::shared_future<T> f = p.get_future(); + std::thread(func5, std::move(p)).detach(); + assert(f.valid()); + f.get(); + assert(f.valid()); + } + { + std::promise<T> p; + std::shared_future<T> f = p.get_future(); + std::thread(func6, std::move(p)).detach(); + try + { + assert(f.valid()); + f.get(); + assert(false); + } + catch (char i) + { + assert(i == 'c'); + } + assert(f.valid()); + } + } +} diff --git a/test/std/thread/futures/futures.shared_future/move_assign.pass.cpp b/test/std/thread/futures/futures.shared_future/move_assign.pass.cpp new file mode 100644 index 000000000000..6b58f41c9085 --- /dev/null +++ b/test/std/thread/futures/futures.shared_future/move_assign.pass.cpp @@ -0,0 +1,76 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class shared_future<R> + +// shared_future& operator=(shared_future&& rhs); + +#include <future> +#include <cassert> + +int main() +{ +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + { + typedef int T; + std::promise<T> p; + std::shared_future<T> f0 = p.get_future(); + std::shared_future<T> f; + f = std::move(f0); + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef int T; + std::shared_future<T> f0; + std::shared_future<T> f; + f = std::move(f0); + assert(!f0.valid()); + assert(!f.valid()); + } + { + typedef int& T; + std::promise<T> p; + std::shared_future<T> f0 = p.get_future(); + std::shared_future<T> f; + f = std::move(f0); + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef int& T; + std::shared_future<T> f0; + std::shared_future<T> f; + f = std::move(f0); + assert(!f0.valid()); + assert(!f.valid()); + } + { + typedef void T; + std::promise<T> p; + std::shared_future<T> f0 = p.get_future(); + std::shared_future<T> f; + f = std::move(f0); + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef void T; + std::shared_future<T> f0; + std::shared_future<T> f; + f = std::move(f0); + assert(!f0.valid()); + assert(!f.valid()); + } +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +} diff --git a/test/std/thread/futures/futures.shared_future/move_ctor.pass.cpp b/test/std/thread/futures/futures.shared_future/move_ctor.pass.cpp new file mode 100644 index 000000000000..32b8fd77c672 --- /dev/null +++ b/test/std/thread/futures/futures.shared_future/move_ctor.pass.cpp @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class shared_future<R> + +// shared_future(shared_future&& rhs); + +#include <future> +#include <cassert> + +int main() +{ + { + typedef int T; + std::promise<T> p; + std::shared_future<T> f0 = p.get_future(); + std::shared_future<T> f = std::move(f0); + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef int T; + std::shared_future<T> f0; + std::shared_future<T> f = std::move(f0); + assert(!f0.valid()); + assert(!f.valid()); + } + { + typedef int& T; + std::promise<T> p; + std::shared_future<T> f0 = p.get_future(); + std::shared_future<T> f = std::move(f0); + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef int& T; + std::shared_future<T> f0; + std::shared_future<T> f = std::move(f0); + assert(!f0.valid()); + assert(!f.valid()); + } + { + typedef void T; + std::promise<T> p; + std::shared_future<T> f0 = p.get_future(); + std::shared_future<T> f = std::move(f0); + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef void T; + std::shared_future<T> f0; + std::shared_future<T> f = std::move(f0); + assert(!f0.valid()); + assert(!f.valid()); + } +} diff --git a/test/std/thread/futures/futures.shared_future/wait.pass.cpp b/test/std/thread/futures/futures.shared_future/wait.pass.cpp new file mode 100644 index 000000000000..4293fcab3564 --- /dev/null +++ b/test/std/thread/futures/futures.shared_future/wait.pass.cpp @@ -0,0 +1,88 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class shared_future<R> + +// void wait() const; + +#include <future> +#include <cassert> + +void func1(std::promise<int> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + p.set_value(3); +} + +int j = 0; + +void func3(std::promise<int&> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + j = 5; + p.set_value(j); +} + +void func5(std::promise<void> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + p.set_value(); +} + +int main() +{ + typedef std::chrono::high_resolution_clock Clock; + typedef std::chrono::duration<double, std::milli> ms; + { + typedef int T; + std::promise<T> p; + std::shared_future<T> f = p.get_future(); + std::thread(func1, std::move(p)).detach(); + assert(f.valid()); + f.wait(); + assert(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + assert(f.valid()); + assert(t1-t0 < ms(5)); + } + { + typedef int& T; + std::promise<T> p; + std::shared_future<T> f = p.get_future(); + std::thread(func3, std::move(p)).detach(); + assert(f.valid()); + f.wait(); + assert(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + assert(f.valid()); + assert(t1-t0 < ms(5)); + } + { + typedef void T; + std::promise<T> p; + std::shared_future<T> f = p.get_future(); + std::thread(func5, std::move(p)).detach(); + assert(f.valid()); + f.wait(); + assert(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + assert(f.valid()); + assert(t1-t0 < ms(5)); + } +} diff --git a/test/std/thread/futures/futures.shared_future/wait_for.pass.cpp b/test/std/thread/futures/futures.shared_future/wait_for.pass.cpp new file mode 100644 index 000000000000..e5a4754e38ad --- /dev/null +++ b/test/std/thread/futures/futures.shared_future/wait_for.pass.cpp @@ -0,0 +1,97 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class shared_future<R> + +// template <class Rep, class Period> +// future_status +// wait_for(const chrono::duration<Rep, Period>& rel_time) const; + +#include <future> +#include <cassert> + +typedef std::chrono::milliseconds ms; + +void func1(std::promise<int> p) +{ + std::this_thread::sleep_for(ms(500)); + p.set_value(3); +} + +int j = 0; + +void func3(std::promise<int&> p) +{ + std::this_thread::sleep_for(ms(500)); + j = 5; + p.set_value(j); +} + +void func5(std::promise<void> p) +{ + std::this_thread::sleep_for(ms(500)); + p.set_value(); +} + +int main() +{ + typedef std::chrono::high_resolution_clock Clock; + { + typedef int T; + std::promise<T> p; + std::shared_future<T> f = p.get_future(); + std::thread(func1, std::move(p)).detach(); + assert(f.valid()); + assert(f.wait_for(ms(300)) == std::future_status::timeout); + assert(f.valid()); + assert(f.wait_for(ms(300)) == std::future_status::ready); + assert(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + assert(f.valid()); + assert(t1-t0 < ms(5)); + } + { + typedef int& T; + std::promise<T> p; + std::shared_future<T> f = p.get_future(); + std::thread(func3, std::move(p)).detach(); + assert(f.valid()); + assert(f.wait_for(ms(300)) == std::future_status::timeout); + assert(f.valid()); + assert(f.wait_for(ms(300)) == std::future_status::ready); + assert(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + assert(f.valid()); + assert(t1-t0 < ms(5)); + } + { + typedef void T; + std::promise<T> p; + std::shared_future<T> f = p.get_future(); + std::thread(func5, std::move(p)).detach(); + assert(f.valid()); + assert(f.wait_for(ms(300)) == std::future_status::timeout); + assert(f.valid()); + assert(f.wait_for(ms(300)) == std::future_status::ready); + assert(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + assert(f.valid()); + assert(t1-t0 < ms(5)); + } +} diff --git a/test/std/thread/futures/futures.shared_future/wait_until.pass.cpp b/test/std/thread/futures/futures.shared_future/wait_until.pass.cpp new file mode 100644 index 000000000000..6a6aeba7759e --- /dev/null +++ b/test/std/thread/futures/futures.shared_future/wait_until.pass.cpp @@ -0,0 +1,129 @@ + //===----------------------------------------------------------------------===// + // + // 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 + + // <future> + + // class shared_future<R> + + // template <class Clock, class Duration> + // future_status + // wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; + + #include <future> + #include <atomic> + #include <cassert> + + enum class WorkerThreadState { Uninitialized, AllowedToRun, Exiting }; + typedef std::chrono::milliseconds ms; + + std::atomic<WorkerThreadState> thread_state(WorkerThreadState::Uninitialized); + + void set_worker_thread_state(WorkerThreadState state) + { + thread_state.store(state, std::memory_order_relaxed); + } + + void wait_for_worker_thread_state(WorkerThreadState state) + { + while (thread_state.load(std::memory_order_relaxed) != state); + } + + void func1(std::promise<int> p) + { + wait_for_worker_thread_state(WorkerThreadState::AllowedToRun); + p.set_value(3); + set_worker_thread_state(WorkerThreadState::Exiting); + } + + int j = 0; + + void func3(std::promise<int&> p) + { + wait_for_worker_thread_state(WorkerThreadState::AllowedToRun); + j = 5; + p.set_value(j); + set_worker_thread_state(WorkerThreadState::Exiting); + } + + void func5(std::promise<void> p) + { + wait_for_worker_thread_state(WorkerThreadState::AllowedToRun); + p.set_value(); + set_worker_thread_state(WorkerThreadState::Exiting); + } + + int main() + { + typedef std::chrono::high_resolution_clock Clock; + { + typedef int T; + std::promise<T> p; + std::shared_future<T> f = p.get_future(); + std::thread(func1, std::move(p)).detach(); + assert(f.valid()); + assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout); + assert(f.valid()); + + // allow the worker thread to produce the result and wait until the worker is done + set_worker_thread_state(WorkerThreadState::AllowedToRun); + wait_for_worker_thread_state(WorkerThreadState::Exiting); + + assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready); + assert(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + assert(f.valid()); + assert(t1-t0 < ms(5)); + } + { + typedef int& T; + std::promise<T> p; + std::shared_future<T> f = p.get_future(); + std::thread(func3, std::move(p)).detach(); + assert(f.valid()); + assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout); + assert(f.valid()); + + // allow the worker thread to produce the result and wait until the worker is done + set_worker_thread_state(WorkerThreadState::AllowedToRun); + wait_for_worker_thread_state(WorkerThreadState::Exiting); + + assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready); + assert(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + assert(f.valid()); + assert(t1-t0 < ms(5)); + } + { + typedef void T; + std::promise<T> p; + std::shared_future<T> f = p.get_future(); + std::thread(func5, std::move(p)).detach(); + assert(f.valid()); + assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout); + assert(f.valid()); + + // allow the worker thread to produce the result and wait until the worker is done + set_worker_thread_state(WorkerThreadState::AllowedToRun); + wait_for_worker_thread_state(WorkerThreadState::Exiting); + + assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready); + assert(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + assert(f.valid()); + assert(t1-t0 < ms(5)); + } + } diff --git a/test/std/thread/futures/futures.state/nothing_to_do.pass.cpp b/test/std/thread/futures/futures.state/nothing_to_do.pass.cpp new file mode 100644 index 000000000000..9a59227abdd9 --- /dev/null +++ b/test/std/thread/futures/futures.state/nothing_to_do.pass.cpp @@ -0,0 +1,13 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +int main() +{ +} diff --git a/test/std/thread/futures/futures.tas/futures.task.members/assign_copy.fail.cpp b/test/std/thread/futures/futures.tas/futures.task.members/assign_copy.fail.cpp new file mode 100644 index 000000000000..70ea0ad31fed --- /dev/null +++ b/test/std/thread/futures/futures.tas/futures.task.members/assign_copy.fail.cpp @@ -0,0 +1,48 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// <future> + +// class packaged_task<R(ArgTypes...)> + +// packaged_task& operator=(packaged_task&) = delete; + +#include <future> +#include <cassert> + +class A +{ + long data_; + +public: + explicit A(long i) : data_(i) {} + + long operator()(long i, long j) const {return data_ + i + j;} +}; + +int main() +{ + { + std::packaged_task<double(int, char)> p0(A(5)); + std::packaged_task<double(int, char)> p; + p = p0; + assert(!p0.valid()); + assert(p.valid()); + std::future<double> f = p.get_future(); + p(3, 'a'); + assert(f.get() == 105.0); + } + { + std::packaged_task<double(int, char)> p0; + std::packaged_task<double(int, char)> p; + p = p0; + assert(!p0.valid()); + assert(!p.valid()); + } +} diff --git a/test/std/thread/futures/futures.tas/futures.task.members/assign_move.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/assign_move.pass.cpp new file mode 100644 index 000000000000..18786f4eb7a2 --- /dev/null +++ b/test/std/thread/futures/futures.tas/futures.task.members/assign_move.pass.cpp @@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class packaged_task<R(ArgTypes...)> + +// packaged_task& operator=(packaged_task&& other); + +#include <future> +#include <cassert> + +class A +{ + long data_; + +public: + explicit A(long i) : data_(i) {} + + long operator()(long i, long j) const {return data_ + i + j;} +}; + +int main() +{ + { + std::packaged_task<double(int, char)> p0(A(5)); + std::packaged_task<double(int, char)> p; + p = std::move(p0); + assert(!p0.valid()); + assert(p.valid()); + std::future<double> f = p.get_future(); + p(3, 'a'); + assert(f.get() == 105.0); + } + { + std::packaged_task<double(int, char)> p0; + std::packaged_task<double(int, char)> p; + p = std::move(p0); + assert(!p0.valid()); + assert(!p.valid()); + } +} diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor1.fail.cpp b/test/std/thread/futures/futures.tas/futures.task.members/ctor1.fail.cpp new file mode 100644 index 000000000000..45048b747f7a --- /dev/null +++ b/test/std/thread/futures/futures.tas/futures.task.members/ctor1.fail.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. +// +//===----------------------------------------------------------------------===// + +// <future> + +// class packaged_task<R(ArgTypes...)> +// template <class F> +// packaged_task(F&& f); +// These constructors shall not participate in overload resolution if +// decay<F>::type is the same type as std::packaged_task<R(ArgTypes...)>. + +#include <future> +#include <cassert> + +struct A {}; +typedef std::packaged_task<A(int, char)> PT; +typedef volatile std::packaged_task<A(int, char)> VPT; + + +int main() +{ + PT p { VPT{} }; +} diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor2.fail.cpp b/test/std/thread/futures/futures.tas/futures.task.members/ctor2.fail.cpp new file mode 100644 index 000000000000..e4df4ec225e7 --- /dev/null +++ b/test/std/thread/futures/futures.tas/futures.task.members/ctor2.fail.cpp @@ -0,0 +1,30 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// <future> + +// class packaged_task<R(ArgTypes...)> +// template <class F, class Allocator> +// packaged_task(allocator_arg_t, const Allocator& a, F&& f); +// These constructors shall not participate in overload resolution if +// decay<F>::type is the same type as std::packaged_task<R(ArgTypes...)>. + +#include <future> +#include <cassert> + +#include "../../test_allocator.h" + +struct A {}; +typedef std::packaged_task<A(int, char)> PT; +typedef volatile std::packaged_task<A(int, char)> VPT; + +int main() +{ + PT p { std::allocator_arg_t{}, test_allocator<A>{}, VPT {}}; +} diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor_copy.fail.cpp b/test/std/thread/futures/futures.tas/futures.task.members/ctor_copy.fail.cpp new file mode 100644 index 000000000000..9884c49a6dc7 --- /dev/null +++ b/test/std/thread/futures/futures.tas/futures.task.members/ctor_copy.fail.cpp @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// <future> + +// class packaged_task<R(ArgTypes...)> + +// packaged_task(packaged_task&) = delete; + +#include <future> +#include <cassert> + +class A +{ + long data_; + +public: + explicit A(long i) : data_(i) {} + + long operator()(long i, long j) const {return data_ + i + j;} +}; + +int main() +{ + { + std::packaged_task<double(int, char)> p0(A(5)); + std::packaged_task<double(int, char)> p(p0); + assert(!p0.valid()); + assert(p.valid()); + std::future<double> f = p.get_future(); + p(3, 'a'); + assert(f.get() == 105.0); + } + { + std::packaged_task<double(int, char)> p0; + std::packaged_task<double(int, char)> p(p0); + assert(!p0.valid()); + assert(!p.valid()); + } +} diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor_default.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/ctor_default.pass.cpp new file mode 100644 index 000000000000..76904962a778 --- /dev/null +++ b/test/std/thread/futures/futures.tas/futures.task.members/ctor_default.pass.cpp @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class packaged_task<R(ArgTypes...)> + +// packaged_task(); + +#include <future> +#include <cassert> + +struct A {}; + +int main() +{ + std::packaged_task<A(int, char)> p; + assert(!p.valid()); +} diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor_func.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/ctor_func.pass.cpp new file mode 100644 index 000000000000..2eee2cbc2d50 --- /dev/null +++ b/test/std/thread/futures/futures.tas/futures.task.members/ctor_func.pass.cpp @@ -0,0 +1,79 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class packaged_task<R(ArgTypes...)> + +// template <class F> +// explicit packaged_task(F&& f); + +#include <future> +#include <cassert> + +class A +{ + long data_; + +public: + static int n_moves; + static int n_copies; + + explicit A(long i) : data_(i) {} + A(A&& a) : data_(a.data_) {++n_moves; a.data_ = -1;} + A(const A& a) : data_(a.data_) {++n_copies;} + + long operator()(long i, long j) const {return data_ + i + j;} +}; + +int A::n_moves = 0; +int A::n_copies = 0; + +int func(int i) { return i; } + +int main() +{ + { + std::packaged_task<double(int, char)> p(A(5)); + assert(p.valid()); + std::future<double> f = p.get_future(); + p(3, 'a'); + assert(f.get() == 105.0); + assert(A::n_copies == 0); + assert(A::n_moves > 0); + } + A::n_copies = 0; + A::n_copies = 0; + { + A a(5); + std::packaged_task<double(int, char)> p(a); + assert(p.valid()); + std::future<double> f = p.get_future(); + p(3, 'a'); + assert(f.get() == 105.0); + assert(A::n_copies > 0); + assert(A::n_moves > 0); + } + { + std::packaged_task<int(int)> p(&func); + assert(p.valid()); + std::future<int> f = p.get_future(); + p(4); + assert(f.get() == 4); + } + { + std::packaged_task<int(int)> p(func); + assert(p.valid()); + std::future<int> f = p.get_future(); + p(4); + assert(f.get() == 4); + } +} diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor_func_alloc.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/ctor_func_alloc.pass.cpp new file mode 100644 index 000000000000..3aac2b26bfc1 --- /dev/null +++ b/test/std/thread/futures/futures.tas/futures.task.members/ctor_func_alloc.pass.cpp @@ -0,0 +1,124 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class packaged_task<R(ArgTypes...)> + +// template <class F, class Allocator> +// explicit packaged_task(allocator_arg_t, const Allocator& a, F&& f); + +#include <future> +#include <cassert> + +#include "../../test_allocator.h" +#include "min_allocator.h" + +class A +{ + long data_; + +public: + static int n_moves; + static int n_copies; + + explicit A(long i) : data_(i) {} + A(A&& a) : data_(a.data_) {++n_moves; a.data_ = -1;} + A(const A& a) : data_(a.data_) {++n_copies;} + + long operator()(long i, long j) const {return data_ + i + j;} +}; + +int A::n_moves = 0; +int A::n_copies = 0; + +int func(int i) { return i; } + +int main() +{ + { + std::packaged_task<double(int, char)> p(std::allocator_arg, + test_allocator<A>(), A(5)); + assert(test_alloc_base::count > 0); + assert(p.valid()); + std::future<double> f = p.get_future(); + p(3, 'a'); + assert(f.get() == 105.0); + assert(A::n_copies == 0); + assert(A::n_moves > 0); + } + assert(test_alloc_base::count == 0); + A::n_copies = 0; + A::n_moves = 0; + { + A a(5); + std::packaged_task<double(int, char)> p(std::allocator_arg, + test_allocator<A>(), a); + assert(test_alloc_base::count > 0); + assert(p.valid()); + std::future<double> f = p.get_future(); + p(3, 'a'); + assert(f.get() == 105.0); + assert(A::n_copies > 0); + assert(A::n_moves > 0); + } + assert(test_alloc_base::count == 0); + A::n_copies = 0; + A::n_moves = 0; + { + A a(5); + std::packaged_task<int(int)> p(std::allocator_arg, test_allocator<A>(), &func); + assert(test_alloc_base::count > 0); + assert(p.valid()); + std::future<int> f = p.get_future(); + p(4); + assert(f.get() == 4); + } + assert(test_alloc_base::count == 0); + A::n_copies = 0; + A::n_moves = 0; + { + A a(5); + std::packaged_task<int(int)> p(std::allocator_arg, test_allocator<A>(), func); + assert(test_alloc_base::count > 0); + assert(p.valid()); + std::future<int> f = p.get_future(); + p(4); + assert(f.get() == 4); + } + assert(test_alloc_base::count == 0); + A::n_copies = 0; + A::n_moves = 0; + { + std::packaged_task<double(int, char)> p(std::allocator_arg, + bare_allocator<void>(), A(5)); + assert(p.valid()); + std::future<double> f = p.get_future(); + p(3, 'a'); + assert(f.get() == 105.0); + assert(A::n_copies == 0); + assert(A::n_moves > 0); + } + A::n_copies = 0; + A::n_moves = 0; + { + std::packaged_task<double(int, char)> p(std::allocator_arg, + min_allocator<void>(), A(5)); + assert(p.valid()); + std::future<double> f = p.get_future(); + p(3, 'a'); + assert(f.get() == 105.0); + assert(A::n_copies == 0); + assert(A::n_moves > 0); + } + A::n_copies = 0; + A::n_moves = 0; +} diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor_move.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/ctor_move.pass.cpp new file mode 100644 index 000000000000..88f072281750 --- /dev/null +++ b/test/std/thread/futures/futures.tas/futures.task.members/ctor_move.pass.cpp @@ -0,0 +1,48 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class packaged_task<R(ArgTypes...)> + +// packaged_task(packaged_task&& other); + +#include <future> +#include <cassert> + +class A +{ + long data_; + +public: + explicit A(long i) : data_(i) {} + + long operator()(long i, long j) const {return data_ + i + j;} +}; + +int main() +{ + { + std::packaged_task<double(int, char)> p0(A(5)); + std::packaged_task<double(int, char)> p = std::move(p0); + assert(!p0.valid()); + assert(p.valid()); + std::future<double> f = p.get_future(); + p(3, 'a'); + assert(f.get() == 105.0); + } + { + std::packaged_task<double(int, char)> p0; + std::packaged_task<double(int, char)> p = std::move(p0); + assert(!p0.valid()); + assert(!p.valid()); + } +} diff --git a/test/std/thread/futures/futures.tas/futures.task.members/dtor.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/dtor.pass.cpp new file mode 100644 index 000000000000..e24232d1b227 --- /dev/null +++ b/test/std/thread/futures/futures.tas/futures.task.members/dtor.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 + +// <future> + +// class packaged_task<R(ArgTypes...)> + +// ~packaged_task(); + +#include <future> +#include <cassert> + +class A +{ + long data_; + +public: + explicit A(long i) : data_(i) {} + + long operator()(long i, long j) const {return data_ + i + j;} +}; + +void func(std::packaged_task<double(int, char)> p) +{ +} + +void func2(std::packaged_task<double(int, char)> p) +{ + p(3, 'a'); +} + +int main() +{ + { + std::packaged_task<double(int, char)> p(A(5)); + std::future<double> f = p.get_future(); + std::thread(func, std::move(p)).detach(); + try + { + double i = f.get(); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::broken_promise)); + } + } + { + std::packaged_task<double(int, char)> p(A(5)); + std::future<double> f = p.get_future(); + std::thread(func2, std::move(p)).detach(); + assert(f.get() == 105.0); + } +} diff --git a/test/std/thread/futures/futures.tas/futures.task.members/get_future.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/get_future.pass.cpp new file mode 100644 index 000000000000..13b5db110668 --- /dev/null +++ b/test/std/thread/futures/futures.tas/futures.task.members/get_future.pass.cpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class packaged_task<R(ArgTypes...)> + +// future<R> get_future(); + +#include <future> +#include <cassert> + +class A +{ + long data_; + +public: + explicit A(long i) : data_(i) {} + + long operator()(long i, long j) const {return data_ + i + j;} +}; + +int main() +{ + { + std::packaged_task<double(int, char)> p(A(5)); + std::future<double> f = p.get_future(); + p(3, 'a'); + assert(f.get() == 105.0); + } + { + std::packaged_task<double(int, char)> p(A(5)); + std::future<double> f = p.get_future(); + try + { + f = p.get_future(); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::future_already_retrieved)); + } + } + { + std::packaged_task<double(int, char)> p; + try + { + std::future<double> f = p.get_future(); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::no_state)); + } + } +} diff --git a/test/std/thread/futures/futures.tas/futures.task.members/make_ready_at_thread_exit.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/make_ready_at_thread_exit.pass.cpp new file mode 100644 index 000000000000..61a6a4f87965 --- /dev/null +++ b/test/std/thread/futures/futures.tas/futures.task.members/make_ready_at_thread_exit.pass.cpp @@ -0,0 +1,106 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class packaged_task<R(ArgTypes...)> + +// void make_ready_at_thread_exit(ArgTypes... args); + +#include <future> +#include <cassert> + +class A +{ + long data_; + +public: + explicit A(long i) : data_(i) {} + + long operator()(long i, long j) const + { + if (j == 'z') + throw A(6); + return data_ + i + j; + } +}; + +void func0(std::packaged_task<double(int, char)> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + p.make_ready_at_thread_exit(3, 'a'); +} + +void func1(std::packaged_task<double(int, char)> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + p.make_ready_at_thread_exit(3, 'z'); +} + +void func2(std::packaged_task<double(int, char)> p) +{ + p.make_ready_at_thread_exit(3, 'a'); + try + { + p.make_ready_at_thread_exit(3, 'c'); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::promise_already_satisfied)); + } +} + +void func3(std::packaged_task<double(int, char)> p) +{ + try + { + p.make_ready_at_thread_exit(3, 'a'); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::no_state)); + } +} + +int main() +{ + { + std::packaged_task<double(int, char)> p(A(5)); + std::future<double> f = p.get_future(); + std::thread(func0, std::move(p)).detach(); + assert(f.get() == 105.0); + } + { + std::packaged_task<double(int, char)> p(A(5)); + std::future<double> f = p.get_future(); + std::thread(func1, std::move(p)).detach(); + try + { + f.get(); + assert(false); + } + catch (const A& e) + { + assert(e(3, 'a') == 106); + } + } + { + std::packaged_task<double(int, char)> p(A(5)); + std::future<double> f = p.get_future(); + std::thread(func2, std::move(p)).detach(); + assert(f.get() == 105.0); + } + { + std::packaged_task<double(int, char)> p; + std::thread t(func3, std::move(p)); + t.join(); + } +} diff --git a/test/std/thread/futures/futures.tas/futures.task.members/operator.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/operator.pass.cpp new file mode 100644 index 000000000000..2a09353b1e63 --- /dev/null +++ b/test/std/thread/futures/futures.tas/futures.task.members/operator.pass.cpp @@ -0,0 +1,107 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class packaged_task<R(ArgTypes...)> + +// void operator()(ArgTypes... args); + +#include <future> +#include <cassert> + +class A +{ + long data_; + +public: + explicit A(long i) : data_(i) {} + + long operator()(long i, long j) const + { + if (j == 'z') + throw A(6); + return data_ + i + j; + } +}; + +void func0(std::packaged_task<double(int, char)> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + p(3, 'a'); +} + +void func1(std::packaged_task<double(int, char)> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + p(3, 'z'); +} + +void func2(std::packaged_task<double(int, char)> p) +{ + p(3, 'a'); + try + { + p(3, 'c'); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::promise_already_satisfied)); + } +} + +void func3(std::packaged_task<double(int, char)> p) +{ + try + { + p(3, 'a'); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::no_state)); + } +} + +int main() +{ + { + std::packaged_task<double(int, char)> p(A(5)); + std::future<double> f = p.get_future(); + std::thread(func0, std::move(p)).detach(); + assert(f.get() == 105.0); + } + { + std::packaged_task<double(int, char)> p(A(5)); + std::future<double> f = p.get_future(); + std::thread(func1, std::move(p)).detach(); + try + { + f.get(); + assert(false); + } + catch (const A& e) + { + assert(e(3, 'a') == 106); + } + } + { + std::packaged_task<double(int, char)> p(A(5)); + std::future<double> f = p.get_future(); + std::thread t(func2, std::move(p)); + assert(f.get() == 105.0); + t.join(); + } + { + std::packaged_task<double(int, char)> p; + std::thread t(func3, std::move(p)); + t.join(); + } +} diff --git a/test/std/thread/futures/futures.tas/futures.task.members/reset.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/reset.pass.cpp new file mode 100644 index 000000000000..9d38d9b409c0 --- /dev/null +++ b/test/std/thread/futures/futures.tas/futures.task.members/reset.pass.cpp @@ -0,0 +1,60 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class packaged_task<R(ArgTypes...)> + +// void reset(); + +#include <future> +#include <cassert> + +class A +{ + long data_; + +public: + explicit A(long i) : data_(i) {} + + long operator()(long i, long j) const + { + if (j == 'z') + throw A(6); + return data_ + i + j; + } +}; + +int main() +{ + { + std::packaged_task<double(int, char)> p(A(5)); + std::future<double> f = p.get_future(); + p(3, 'a'); + assert(f.get() == 105.0); + p.reset(); + p(4, 'a'); + f = p.get_future(); + assert(f.get() == 106.0); + } + { + std::packaged_task<double(int, char)> p; + try + { + p.reset(); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::no_state)); + } + } +} diff --git a/test/std/thread/futures/futures.tas/futures.task.members/swap.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/swap.pass.cpp new file mode 100644 index 000000000000..33763bef0d0f --- /dev/null +++ b/test/std/thread/futures/futures.tas/futures.task.members/swap.pass.cpp @@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class packaged_task<R(ArgTypes...)> + +// void swap(packaged_task& other); + +#include <future> +#include <cassert> + +class A +{ + long data_; + +public: + explicit A(long i) : data_(i) {} + + long operator()(long i, long j) const {return data_ + i + j;} +}; + +int main() +{ + { + std::packaged_task<double(int, char)> p0(A(5)); + std::packaged_task<double(int, char)> p; + p.swap(p0); + assert(!p0.valid()); + assert(p.valid()); + std::future<double> f = p.get_future(); + p(3, 'a'); + assert(f.get() == 105.0); + } + { + std::packaged_task<double(int, char)> p0; + std::packaged_task<double(int, char)> p; + p.swap(p0); + assert(!p0.valid()); + assert(!p.valid()); + } +} diff --git a/test/std/thread/futures/futures.tas/futures.task.nonmembers/swap.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.nonmembers/swap.pass.cpp new file mode 100644 index 000000000000..668732b9b24a --- /dev/null +++ b/test/std/thread/futures/futures.tas/futures.task.nonmembers/swap.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 + +// <future> + +// class packaged_task<R(ArgTypes...)> + +// template <class R, class... ArgTypes> +// void +// swap(packaged_task<R(ArgTypes...)>& x, packaged_task<R(ArgTypes...)>& y); + +#include <future> +#include <cassert> + +class A +{ + long data_; + +public: + explicit A(long i) : data_(i) {} + + long operator()(long i, long j) const {return data_ + i + j;} +}; + +int main() +{ + { + std::packaged_task<double(int, char)> p0(A(5)); + std::packaged_task<double(int, char)> p; + swap(p, p0); + assert(!p0.valid()); + assert(p.valid()); + std::future<double> f = p.get_future(); + p(3, 'a'); + assert(f.get() == 105.0); + } + { + std::packaged_task<double(int, char)> p0; + std::packaged_task<double(int, char)> p; + swap(p, p0); + assert(!p0.valid()); + assert(!p.valid()); + } +} diff --git a/test/std/thread/futures/futures.tas/futures.task.nonmembers/uses_allocator.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.nonmembers/uses_allocator.pass.cpp new file mode 100644 index 000000000000..986f71e29a46 --- /dev/null +++ b/test/std/thread/futures/futures.tas/futures.task.nonmembers/uses_allocator.pass.cpp @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class packaged_task<R(ArgTypes...)> + +// template <class Callable, class Alloc> +// struct uses_allocator<packaged_task<Callable>, Alloc> +// : true_type { }; + +#include <future> +#include "../../test_allocator.h" + +int main() +{ + static_assert((std::uses_allocator<std::packaged_task<double(int, char)>, test_allocator<int> >::value), ""); +} diff --git a/test/std/thread/futures/futures.tas/types.pass.cpp b/test/std/thread/futures/futures.tas/types.pass.cpp new file mode 100644 index 000000000000..dd1724ddbda5 --- /dev/null +++ b/test/std/thread/futures/futures.tas/types.pass.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// template<class R, class... ArgTypes> +// class packaged_task<R(ArgTypes...)> +// { +// public: +// typedef R result_type; + +#include <future> +#include <type_traits> + +struct A {}; + +int main() +{ + static_assert((std::is_same<std::packaged_task<A(int, char)>::result_type, A>::value), ""); +} diff --git a/test/std/thread/futures/futures.unique_future/copy_assign.fail.cpp b/test/std/thread/futures/futures.unique_future/copy_assign.fail.cpp new file mode 100644 index 000000000000..ebdcbf98d996 --- /dev/null +++ b/test/std/thread/futures/futures.unique_future/copy_assign.fail.cpp @@ -0,0 +1,74 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// <future> + +// class future<R> + +// future& operator=(const future&) = delete; + +#include <future> +#include <cassert> + +int main() +{ +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + { + typedef int T; + std::promise<T> p; + std::future<T> f0 = p.get_future(); + std::future<T> f; + f = f0; + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef int T; + std::future<T> f0; + std::future<T> f; + f = f0; + assert(!f0.valid()); + assert(!f.valid()); + } + { + typedef int& T; + std::promise<T> p; + std::future<T> f0 = p.get_future(); + std::future<T> f; + f = f0; + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef int& T; + std::future<T> f0; + std::future<T> f; + f = f0; + assert(!f0.valid()); + assert(!f.valid()); + } + { + typedef void T; + std::promise<T> p; + std::future<T> f0 = p.get_future(); + std::future<T> f; + f = f0; + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef void T; + std::future<T> f0; + std::future<T> f; + f = f0; + assert(!f0.valid()); + assert(!f.valid()); + } +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +} diff --git a/test/std/thread/futures/futures.unique_future/copy_ctor.fail.cpp b/test/std/thread/futures/futures.unique_future/copy_ctor.fail.cpp new file mode 100644 index 000000000000..8d43294edc26 --- /dev/null +++ b/test/std/thread/futures/futures.unique_future/copy_ctor.fail.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. +// +//===----------------------------------------------------------------------===// + +// <future> + +// class future<R> + +// future(const future&) = delete; + +#include <future> +#include <cassert> + +int main() +{ + { + typedef int T; + std::promise<T> p; + std::future<T> f0 = p.get_future(); + std::future<T> f = f0; + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef int T; + std::future<T> f0; + std::future<T> f = f0; + assert(!f0.valid()); + assert(!f.valid()); + } + { + typedef int& T; + std::promise<T> p; + std::future<T> f0 = p.get_future(); + std::future<T> f = f0; + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef int& T; + std::future<T> f0; + std::future<T> f = std::move(f0); + assert(!f0.valid()); + assert(!f.valid()); + } + { + typedef void T; + std::promise<T> p; + std::future<T> f0 = p.get_future(); + std::future<T> f = f0; + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef void T; + std::future<T> f0; + std::future<T> f = f0; + assert(!f0.valid()); + assert(!f.valid()); + } +} diff --git a/test/std/thread/futures/futures.unique_future/default.pass.cpp b/test/std/thread/futures/futures.unique_future/default.pass.cpp new file mode 100644 index 000000000000..84cb84650dcd --- /dev/null +++ b/test/std/thread/futures/futures.unique_future/default.pass.cpp @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class future<R> + +// future(); + +#include <future> +#include <cassert> + +int main() +{ + { + std::future<int> f; + assert(!f.valid()); + } + { + std::future<int&> f; + assert(!f.valid()); + } + { + std::future<void> f; + assert(!f.valid()); + } +} diff --git a/test/std/thread/futures/futures.unique_future/dtor.pass.cpp b/test/std/thread/futures/futures.unique_future/dtor.pass.cpp new file mode 100644 index 000000000000..5e9697bb939b --- /dev/null +++ b/test/std/thread/futures/futures.unique_future/dtor.pass.cpp @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class future<R> + +// ~future(); + +#include <future> +#include <cassert> + +#include "../test_allocator.h" + +int main() +{ + assert(test_alloc_base::count == 0); + { + typedef int T; + std::future<T> f; + { + std::promise<T> p(std::allocator_arg, test_allocator<T>()); + assert(test_alloc_base::count == 1); + f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + } + assert(test_alloc_base::count == 1); + assert(f.valid()); + } + assert(test_alloc_base::count == 0); + { + typedef int& T; + std::future<T> f; + { + std::promise<T> p(std::allocator_arg, test_allocator<int>()); + assert(test_alloc_base::count == 1); + f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + } + assert(test_alloc_base::count == 1); + assert(f.valid()); + } + assert(test_alloc_base::count == 0); + { + typedef void T; + std::future<T> f; + { + std::promise<T> p(std::allocator_arg, test_allocator<T>()); + assert(test_alloc_base::count == 1); + f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + } + assert(test_alloc_base::count == 1); + assert(f.valid()); + } + assert(test_alloc_base::count == 0); +} diff --git a/test/std/thread/futures/futures.unique_future/get.pass.cpp b/test/std/thread/futures/futures.unique_future/get.pass.cpp new file mode 100644 index 000000000000..758e38a7dae9 --- /dev/null +++ b/test/std/thread/futures/futures.unique_future/get.pass.cpp @@ -0,0 +1,145 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class future<R> + +// R future::get(); +// R& future<R&>::get(); +// void future<void>::get(); + +#include <future> +#include <cassert> + +void func1(std::promise<int> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + p.set_value(3); +} + +void func2(std::promise<int> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + p.set_exception(std::make_exception_ptr(3)); +} + +int j = 0; + +void func3(std::promise<int&> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + j = 5; + p.set_value(j); +} + +void func4(std::promise<int&> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + p.set_exception(std::make_exception_ptr(3.5)); +} + +void func5(std::promise<void> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + p.set_value(); +} + +void func6(std::promise<void> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + p.set_exception(std::make_exception_ptr('c')); +} + +int main() +{ + { + typedef int T; + { + std::promise<T> p; + std::future<T> f = p.get_future(); + std::thread(func1, std::move(p)).detach(); + assert(f.valid()); + assert(f.get() == 3); + assert(!f.valid()); + } + { + std::promise<T> p; + std::future<T> f = p.get_future(); + std::thread(func2, std::move(p)).detach(); + try + { + assert(f.valid()); + assert(f.get() == 3); + assert(false); + } + catch (int i) + { + assert(i == 3); + } + assert(!f.valid()); + } + } + { + typedef int& T; + { + std::promise<T> p; + std::future<T> f = p.get_future(); + std::thread(func3, std::move(p)).detach(); + assert(f.valid()); + assert(f.get() == 5); + assert(!f.valid()); + } + { + std::promise<T> p; + std::future<T> f = p.get_future(); + std::thread(func4, std::move(p)).detach(); + try + { + assert(f.valid()); + assert(f.get() == 3); + assert(false); + } + catch (double i) + { + assert(i == 3.5); + } + assert(!f.valid()); + } + } + { + typedef void T; + { + std::promise<T> p; + std::future<T> f = p.get_future(); + std::thread(func5, std::move(p)).detach(); + assert(f.valid()); + f.get(); + assert(!f.valid()); + } + { + std::promise<T> p; + std::future<T> f = p.get_future(); + std::thread(func6, std::move(p)).detach(); + try + { + assert(f.valid()); + f.get(); + assert(false); + } + catch (char i) + { + assert(i == 'c'); + } + assert(!f.valid()); + } + } +} diff --git a/test/std/thread/futures/futures.unique_future/move_assign.pass.cpp b/test/std/thread/futures/futures.unique_future/move_assign.pass.cpp new file mode 100644 index 000000000000..8d38b81f0cda --- /dev/null +++ b/test/std/thread/futures/futures.unique_future/move_assign.pass.cpp @@ -0,0 +1,76 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class future<R> + +// future& operator=(future&& rhs); + +#include <future> +#include <cassert> + +int main() +{ +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + { + typedef int T; + std::promise<T> p; + std::future<T> f0 = p.get_future(); + std::future<T> f; + f = std::move(f0); + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef int T; + std::future<T> f0; + std::future<T> f; + f = std::move(f0); + assert(!f0.valid()); + assert(!f.valid()); + } + { + typedef int& T; + std::promise<T> p; + std::future<T> f0 = p.get_future(); + std::future<T> f; + f = std::move(f0); + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef int& T; + std::future<T> f0; + std::future<T> f; + f = std::move(f0); + assert(!f0.valid()); + assert(!f.valid()); + } + { + typedef void T; + std::promise<T> p; + std::future<T> f0 = p.get_future(); + std::future<T> f; + f = std::move(f0); + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef void T; + std::future<T> f0; + std::future<T> f; + f = std::move(f0); + assert(!f0.valid()); + assert(!f.valid()); + } +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +} diff --git a/test/std/thread/futures/futures.unique_future/move_ctor.pass.cpp b/test/std/thread/futures/futures.unique_future/move_ctor.pass.cpp new file mode 100644 index 000000000000..e12c920886fa --- /dev/null +++ b/test/std/thread/futures/futures.unique_future/move_ctor.pass.cpp @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class future<R> + +// future(future&& rhs); + +#include <future> +#include <cassert> + +int main() +{ +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + { + typedef int T; + std::promise<T> p; + std::future<T> f0 = p.get_future(); + std::future<T> f = std::move(f0); + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef int T; + std::future<T> f0; + std::future<T> f = std::move(f0); + assert(!f0.valid()); + assert(!f.valid()); + } + { + typedef int& T; + std::promise<T> p; + std::future<T> f0 = p.get_future(); + std::future<T> f = std::move(f0); + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef int& T; + std::future<T> f0; + std::future<T> f = std::move(f0); + assert(!f0.valid()); + assert(!f.valid()); + } + { + typedef void T; + std::promise<T> p; + std::future<T> f0 = p.get_future(); + std::future<T> f = std::move(f0); + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef void T; + std::future<T> f0; + std::future<T> f = std::move(f0); + assert(!f0.valid()); + assert(!f.valid()); + } +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +} diff --git a/test/std/thread/futures/futures.unique_future/share.pass.cpp b/test/std/thread/futures/futures.unique_future/share.pass.cpp new file mode 100644 index 000000000000..794b5ce38feb --- /dev/null +++ b/test/std/thread/futures/futures.unique_future/share.pass.cpp @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class future<R> + +// shared_future<R> share() &&; + +#include <future> +#include <cassert> + +int main() +{ + { + typedef int T; + std::promise<T> p; + std::future<T> f0 = p.get_future(); + std::shared_future<T> f = std::move(f0.share()); + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef int T; + std::future<T> f0; + std::shared_future<T> f = std::move(f0.share()); + assert(!f0.valid()); + assert(!f.valid()); + } + { + typedef int& T; + std::promise<T> p; + std::future<T> f0 = p.get_future(); + std::shared_future<T> f = std::move(f0.share()); + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef int& T; + std::future<T> f0; + std::shared_future<T> f = std::move(f0.share()); + assert(!f0.valid()); + assert(!f.valid()); + } + { + typedef void T; + std::promise<T> p; + std::future<T> f0 = p.get_future(); + std::shared_future<T> f = std::move(f0.share()); + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef void T; + std::future<T> f0; + std::shared_future<T> f = std::move(f0.share()); + assert(!f0.valid()); + assert(!f.valid()); + } +} diff --git a/test/std/thread/futures/futures.unique_future/wait.pass.cpp b/test/std/thread/futures/futures.unique_future/wait.pass.cpp new file mode 100644 index 000000000000..e10d37cf8064 --- /dev/null +++ b/test/std/thread/futures/futures.unique_future/wait.pass.cpp @@ -0,0 +1,88 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class future<R> + +// void wait() const; + +#include <future> +#include <cassert> + +void func1(std::promise<int> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + p.set_value(3); +} + +int j = 0; + +void func3(std::promise<int&> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + j = 5; + p.set_value(j); +} + +void func5(std::promise<void> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + p.set_value(); +} + +int main() +{ + typedef std::chrono::high_resolution_clock Clock; + typedef std::chrono::duration<double, std::milli> ms; + { + typedef int T; + std::promise<T> p; + std::future<T> f = p.get_future(); + std::thread(func1, std::move(p)).detach(); + assert(f.valid()); + f.wait(); + assert(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + assert(f.valid()); + assert(t1-t0 < ms(5)); + } + { + typedef int& T; + std::promise<T> p; + std::future<T> f = p.get_future(); + std::thread(func3, std::move(p)).detach(); + assert(f.valid()); + f.wait(); + assert(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + assert(f.valid()); + assert(t1-t0 < ms(5)); + } + { + typedef void T; + std::promise<T> p; + std::future<T> f = p.get_future(); + std::thread(func5, std::move(p)).detach(); + assert(f.valid()); + f.wait(); + assert(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + assert(f.valid()); + assert(t1-t0 < ms(5)); + } +} diff --git a/test/std/thread/futures/futures.unique_future/wait_for.pass.cpp b/test/std/thread/futures/futures.unique_future/wait_for.pass.cpp new file mode 100644 index 000000000000..0a381d9ca2f0 --- /dev/null +++ b/test/std/thread/futures/futures.unique_future/wait_for.pass.cpp @@ -0,0 +1,97 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <future> + +// class future<R> + +// template <class Rep, class Period> +// future_status +// wait_for(const chrono::duration<Rep, Period>& rel_time) const; + +#include <future> +#include <cassert> + +typedef std::chrono::milliseconds ms; + +void func1(std::promise<int> p) +{ + std::this_thread::sleep_for(ms(500)); + p.set_value(3); +} + +int j = 0; + +void func3(std::promise<int&> p) +{ + std::this_thread::sleep_for(ms(500)); + j = 5; + p.set_value(j); +} + +void func5(std::promise<void> p) +{ + std::this_thread::sleep_for(ms(500)); + p.set_value(); +} + +int main() +{ + typedef std::chrono::high_resolution_clock Clock; + { + typedef int T; + std::promise<T> p; + std::future<T> f = p.get_future(); + std::thread(func1, std::move(p)).detach(); + assert(f.valid()); + assert(f.wait_for(ms(300)) == std::future_status::timeout); + assert(f.valid()); + assert(f.wait_for(ms(300)) == std::future_status::ready); + assert(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + assert(f.valid()); + assert(t1-t0 < ms(50)); + } + { + typedef int& T; + std::promise<T> p; + std::future<T> f = p.get_future(); + std::thread(func3, std::move(p)).detach(); + assert(f.valid()); + assert(f.wait_for(ms(300)) == std::future_status::timeout); + assert(f.valid()); + assert(f.wait_for(ms(300)) == std::future_status::ready); + assert(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + assert(f.valid()); + assert(t1-t0 < ms(50)); + } + { + typedef void T; + std::promise<T> p; + std::future<T> f = p.get_future(); + std::thread(func5, std::move(p)).detach(); + assert(f.valid()); + assert(f.wait_for(ms(300)) == std::future_status::timeout); + assert(f.valid()); + assert(f.wait_for(ms(300)) == std::future_status::ready); + assert(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + assert(f.valid()); + assert(t1-t0 < ms(50)); + } +} diff --git a/test/std/thread/futures/futures.unique_future/wait_until.pass.cpp b/test/std/thread/futures/futures.unique_future/wait_until.pass.cpp new file mode 100644 index 000000000000..d5865b9b9dcf --- /dev/null +++ b/test/std/thread/futures/futures.unique_future/wait_until.pass.cpp @@ -0,0 +1,129 @@ + //===----------------------------------------------------------------------===// + // + // 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 + + // <future> + + // class future<R> + + // template <class Clock, class Duration> + // future_status + // wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; + + #include <future> + #include <atomic> + #include <cassert> + + enum class WorkerThreadState { Uninitialized, AllowedToRun, Exiting }; + typedef std::chrono::milliseconds ms; + + std::atomic<WorkerThreadState> thread_state(WorkerThreadState::Uninitialized); + + void set_worker_thread_state(WorkerThreadState state) + { + thread_state.store(state, std::memory_order_relaxed); + } + + void wait_for_worker_thread_state(WorkerThreadState state) + { + while (thread_state.load(std::memory_order_relaxed) != state); + } + + void func1(std::promise<int> p) + { + wait_for_worker_thread_state(WorkerThreadState::AllowedToRun); + p.set_value(3); + set_worker_thread_state(WorkerThreadState::Exiting); + } + + int j = 0; + + void func3(std::promise<int&> p) + { + wait_for_worker_thread_state(WorkerThreadState::AllowedToRun); + j = 5; + p.set_value(j); + set_worker_thread_state(WorkerThreadState::Exiting); + } + + void func5(std::promise<void> p) + { + wait_for_worker_thread_state(WorkerThreadState::AllowedToRun); + p.set_value(); + set_worker_thread_state(WorkerThreadState::Exiting); + } + + int main() + { + typedef std::chrono::high_resolution_clock Clock; + { + typedef int T; + std::promise<T> p; + std::future<T> f = p.get_future(); + std::thread(func1, std::move(p)).detach(); + assert(f.valid()); + assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout); + assert(f.valid()); + + // allow the worker thread to produce the result and wait until the worker is done + set_worker_thread_state(WorkerThreadState::AllowedToRun); + wait_for_worker_thread_state(WorkerThreadState::Exiting); + + assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready); + assert(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + assert(f.valid()); + assert(t1-t0 < ms(5)); + } + { + typedef int& T; + std::promise<T> p; + std::future<T> f = p.get_future(); + std::thread(func3, std::move(p)).detach(); + assert(f.valid()); + assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout); + assert(f.valid()); + + // allow the worker thread to produce the result and wait until the worker is done + set_worker_thread_state(WorkerThreadState::AllowedToRun); + wait_for_worker_thread_state(WorkerThreadState::Exiting); + + assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready); + assert(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + assert(f.valid()); + assert(t1-t0 < ms(5)); + } + { + typedef void T; + std::promise<T> p; + std::future<T> f = p.get_future(); + std::thread(func5, std::move(p)).detach(); + assert(f.valid()); + assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout); + assert(f.valid()); + + // allow the worker thread to produce the result and wait until the worker is done + set_worker_thread_state(WorkerThreadState::AllowedToRun); + wait_for_worker_thread_state(WorkerThreadState::Exiting); + + assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready); + assert(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + assert(f.valid()); + assert(t1-t0 < ms(5)); + } + } diff --git a/test/std/thread/futures/test_allocator.h b/test/std/thread/futures/test_allocator.h new file mode 100644 index 000000000000..50072909fa4e --- /dev/null +++ b/test/std/thread/futures/test_allocator.h @@ -0,0 +1,158 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +#ifndef TEST_ALLOCATOR_H +#define TEST_ALLOCATOR_H + +#include <cstddef> +#include <type_traits> +#include <utility> +#include <cstdlib> +#include <new> +#include <climits> + +class test_alloc_base +{ +public: + static int count; +public: + static int throw_after; +}; + +int test_alloc_base::count = 0; +int test_alloc_base::throw_after = INT_MAX; + +template <class T> +class test_allocator + : public test_alloc_base +{ + int data_; + + template <class U> friend class test_allocator; +public: + + typedef unsigned size_type; + typedef int difference_type; + typedef T value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef typename std::add_lvalue_reference<value_type>::type reference; + typedef typename std::add_lvalue_reference<const value_type>::type const_reference; + + template <class U> struct rebind {typedef test_allocator<U> other;}; + + test_allocator() throw() : data_(-1) {} + explicit test_allocator(int i) throw() : data_(i) {} + test_allocator(const test_allocator& a) throw() + : data_(a.data_) {} + template <class U> test_allocator(const test_allocator<U>& a) throw() + : data_(a.data_) {} + ~test_allocator() throw() {data_ = 0;} + pointer address(reference x) const {return &x;} + const_pointer address(const_reference x) const {return &x;} + pointer allocate(size_type n, const void* = 0) + { + if (count >= throw_after) { +#ifndef _LIBCPP_NO_EXCEPTIONS + throw std::bad_alloc(); +#else + std::terminate(); +#endif + } + ++count; + return (pointer)std::malloc(n * sizeof(T)); + } + void deallocate(pointer p, size_type n) + {--count; std::free(p);} + size_type max_size() const throw() + {return UINT_MAX / sizeof(T);} + void construct(pointer p, const T& val) + {::new(p) T(val);} +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + void construct(pointer p, T&& val) + {::new(p) T(std::move(val));} +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + void destroy(pointer p) {p->~T();} + + friend bool operator==(const test_allocator& x, const test_allocator& y) + {return x.data_ == y.data_;} + friend bool operator!=(const test_allocator& x, const test_allocator& y) + {return !(x == y);} +}; + +template <> +class test_allocator<void> + : public test_alloc_base +{ + int data_; + + template <class U> friend class test_allocator; +public: + + typedef unsigned size_type; + typedef int difference_type; + typedef void value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + + template <class U> struct rebind {typedef test_allocator<U> other;}; + + test_allocator() throw() : data_(-1) {} + explicit test_allocator(int i) throw() : data_(i) {} + test_allocator(const test_allocator& a) throw() + : data_(a.data_) {} + template <class U> test_allocator(const test_allocator<U>& a) throw() + : data_(a.data_) {} + ~test_allocator() throw() {data_ = 0;} + + friend bool operator==(const test_allocator& x, const test_allocator& y) + {return x.data_ == y.data_;} + friend bool operator!=(const test_allocator& x, const test_allocator& y) + {return !(x == y);} +}; + +template <class T> +class other_allocator +{ + int data_; + + template <class U> friend class other_allocator; + +public: + typedef T value_type; + + other_allocator() : data_(-1) {} + explicit other_allocator(int i) : data_(i) {} + template <class U> other_allocator(const other_allocator<U>& a) + : data_(a.data_) {} + T* allocate(std::size_t n) + {return (T*)std::malloc(n * sizeof(T));} + void deallocate(T* p, std::size_t n) + {std::free(p);} + + other_allocator select_on_container_copy_construction() const + {return other_allocator(-2);} + + friend bool operator==(const other_allocator& x, const other_allocator& y) + {return x.data_ == y.data_;} + friend bool operator!=(const other_allocator& x, const other_allocator& y) + {return !(x == y);} + + typedef std::true_type propagate_on_container_copy_assignment; + typedef std::true_type propagate_on_container_move_assignment; + typedef std::true_type propagate_on_container_swap; + +#ifdef _LIBCPP_HAS_NO_ADVANCED_SFINAE + std::size_t max_size() const + {return UINT_MAX / sizeof(T);} +#endif // _LIBCPP_HAS_NO_ADVANCED_SFINAE + +}; + +#endif // TEST_ALLOCATOR_H diff --git a/test/std/thread/futures/version.pass.cpp b/test/std/thread/futures/version.pass.cpp new file mode 100644 index 000000000000..6730a1477db7 --- /dev/null +++ b/test/std/thread/futures/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 + +// <future> + +#include <future> + +#ifndef _LIBCPP_VERSION +#error _LIBCPP_VERSION not defined +#endif + +int main() +{ +} diff --git a/test/std/thread/macro.pass.cpp b/test/std/thread/macro.pass.cpp new file mode 100644 index 000000000000..c1b1377d6cc3 --- /dev/null +++ b/test/std/thread/macro.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 + +// <thread> + +// #define __STDCPP_THREADS__ __cplusplus + +#include <thread> + +int main() +{ +#ifndef __STDCPP_THREADS__ +#error __STDCPP_THREADS__ is not defined +#endif +} diff --git a/test/std/thread/thread.condition/cv_status.pass.cpp b/test/std/thread/thread.condition/cv_status.pass.cpp new file mode 100644 index 000000000000..fe5fa05ad247 --- /dev/null +++ b/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/test/std/thread/thread.condition/notify_all_at_thread_exit.pass.cpp b/test/std/thread/thread.condition/notify_all_at_thread_exit.pass.cpp new file mode 100644 index 000000000000..2b8772f92ed2 --- /dev/null +++ b/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/test/std/thread/thread.condition/thread.condition.condvar/assign.fail.cpp b/test/std/thread/thread.condition/thread.condition.condvar/assign.fail.cpp new file mode 100644 index 000000000000..e88550c5b8ad --- /dev/null +++ b/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/test/std/thread/thread.condition/thread.condition.condvar/copy.fail.cpp b/test/std/thread/thread.condition/thread.condition.condvar/copy.fail.cpp new file mode 100644 index 000000000000..24d6ee0e71d2 --- /dev/null +++ b/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/test/std/thread/thread.condition/thread.condition.condvar/default.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvar/default.pass.cpp new file mode 100644 index 000000000000..6f43564c3b3d --- /dev/null +++ b/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/test/std/thread/thread.condition/thread.condition.condvar/destructor.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvar/destructor.pass.cpp new file mode 100644 index 000000000000..437ed965b191 --- /dev/null +++ b/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/test/std/thread/thread.condition/thread.condition.condvar/native_handle.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvar/native_handle.pass.cpp new file mode 100644 index 000000000000..bf28e01a0e86 --- /dev/null +++ b/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/test/std/thread/thread.condition/thread.condition.condvar/notify_all.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvar/notify_all.pass.cpp new file mode 100644 index 000000000000..fd80ee99c968 --- /dev/null +++ b/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/test/std/thread/thread.condition/thread.condition.condvar/notify_one.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvar/notify_one.pass.cpp new file mode 100644 index 000000000000..6236a13df80e --- /dev/null +++ b/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/test/std/thread/thread.condition/thread.condition.condvar/wait.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvar/wait.pass.cpp new file mode 100644 index 000000000000..236eecc919ad --- /dev/null +++ b/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/test/std/thread/thread.condition/thread.condition.condvar/wait_for.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvar/wait_for.pass.cpp new file mode 100644 index 000000000000..ca48eee19d27 --- /dev/null +++ b/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/test/std/thread/thread.condition/thread.condition.condvar/wait_for_pred.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvar/wait_for_pred.pass.cpp new file mode 100644 index 000000000000..0ee40d161b7b --- /dev/null +++ b/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/test/std/thread/thread.condition/thread.condition.condvar/wait_pred.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvar/wait_pred.pass.cpp new file mode 100644 index 000000000000..45e0b8124165 --- /dev/null +++ b/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/test/std/thread/thread.condition/thread.condition.condvar/wait_until.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvar/wait_until.pass.cpp new file mode 100644 index 000000000000..d87a188e93d7 --- /dev/null +++ b/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/test/std/thread/thread.condition/thread.condition.condvar/wait_until_pred.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvar/wait_until_pred.pass.cpp new file mode 100644 index 000000000000..90ffb1d0b29d --- /dev/null +++ b/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/test/std/thread/thread.condition/thread.condition.condvarany/assign.fail.cpp b/test/std/thread/thread.condition/thread.condition.condvarany/assign.fail.cpp new file mode 100644 index 000000000000..0b8d8e965e63 --- /dev/null +++ b/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/test/std/thread/thread.condition/thread.condition.condvarany/copy.fail.cpp b/test/std/thread/thread.condition/thread.condition.condvarany/copy.fail.cpp new file mode 100644 index 000000000000..84902546d07d --- /dev/null +++ b/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/test/std/thread/thread.condition/thread.condition.condvarany/default.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvarany/default.pass.cpp new file mode 100644 index 000000000000..210060a7461b --- /dev/null +++ b/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/test/std/thread/thread.condition/thread.condition.condvarany/destructor.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvarany/destructor.pass.cpp new file mode 100644 index 000000000000..6bdca7b010c2 --- /dev/null +++ b/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/test/std/thread/thread.condition/thread.condition.condvarany/notify_all.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvarany/notify_all.pass.cpp new file mode 100644 index 000000000000..27ead95682a4 --- /dev/null +++ b/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/test/std/thread/thread.condition/thread.condition.condvarany/notify_one.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvarany/notify_one.pass.cpp new file mode 100644 index 000000000000..98f6c432c977 --- /dev/null +++ b/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/test/std/thread/thread.condition/thread.condition.condvarany/wait.exception.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvarany/wait.exception.pass.cpp new file mode 100644 index 000000000000..522c61b02d17 --- /dev/null +++ b/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/test/std/thread/thread.condition/thread.condition.condvarany/wait.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvarany/wait.pass.cpp new file mode 100644 index 000000000000..f5c8926e34b3 --- /dev/null +++ b/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/test/std/thread/thread.condition/thread.condition.condvarany/wait_for.exception.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvarany/wait_for.exception.pass.cpp new file mode 100644 index 000000000000..1906b5892506 --- /dev/null +++ b/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/test/std/thread/thread.condition/thread.condition.condvarany/wait_for.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvarany/wait_for.pass.cpp new file mode 100644 index 000000000000..a4b4ed991f29 --- /dev/null +++ b/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/test/std/thread/thread.condition/thread.condition.condvarany/wait_for_pred.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvarany/wait_for_pred.pass.cpp new file mode 100644 index 000000000000..b2403079275d --- /dev/null +++ b/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/test/std/thread/thread.condition/thread.condition.condvarany/wait_pred.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvarany/wait_pred.pass.cpp new file mode 100644 index 000000000000..921ad69f145e --- /dev/null +++ b/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/test/std/thread/thread.condition/thread.condition.condvarany/wait_until.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvarany/wait_until.pass.cpp new file mode 100644 index 000000000000..1994ebdfe609 --- /dev/null +++ b/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/test/std/thread/thread.condition/thread.condition.condvarany/wait_until_pred.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvarany/wait_until_pred.pass.cpp new file mode 100644 index 000000000000..c0fea0355b9c --- /dev/null +++ b/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/test/std/thread/thread.condition/version.pass.cpp b/test/std/thread/thread.condition/version.pass.cpp new file mode 100644 index 000000000000..12a775e83398 --- /dev/null +++ b/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() +{ +} diff --git a/test/std/thread/thread.general/nothing_to_do.pass.cpp b/test/std/thread/thread.general/nothing_to_do.pass.cpp new file mode 100644 index 000000000000..b58f5c55b643 --- /dev/null +++ b/test/std/thread/thread.general/nothing_to_do.pass.cpp @@ -0,0 +1,12 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +int main() +{ +} diff --git a/test/std/thread/thread.mutex/thread.lock.algorithm/lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock.algorithm/lock.pass.cpp new file mode 100644 index 000000000000..f67ca2169825 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock.algorithm/lock.pass.cpp @@ -0,0 +1,507 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <mutex> + +// template <class L1, class L2, class... L3> +// void lock(L1&, L2&, L3&...); + +#include <mutex> +#include <cassert> + +class L0 +{ + bool locked_; + +public: + L0() : locked_(false) {} + + void lock() + { + locked_ = true; + } + + bool try_lock() + { + locked_ = true; + return locked_; + } + + void unlock() {locked_ = false;} + + bool locked() const {return locked_;} +}; + +class L1 +{ + bool locked_; + +public: + L1() : locked_(false) {} + + void lock() + { + locked_ = true; + } + + bool try_lock() + { + locked_ = false; + return locked_; + } + + void unlock() {locked_ = false;} + + bool locked() const {return locked_;} +}; + +class L2 +{ + bool locked_; + +public: + L2() : locked_(false) {} + + void lock() + { + throw 1; + } + + bool try_lock() + { + throw 1; + return locked_; + } + + void unlock() {locked_ = false;} + + bool locked() const {return locked_;} +}; + +int main() +{ + { + L0 l0; + L0 l1; + std::lock(l0, l1); + assert(l0.locked()); + assert(l1.locked()); + } + { + L0 l0; + L1 l1; + std::lock(l0, l1); + assert(l0.locked()); + assert(l1.locked()); + } + { + L1 l0; + L0 l1; + std::lock(l0, l1); + assert(l0.locked()); + assert(l1.locked()); + } + { + L0 l0; + L2 l1; + try + { + std::lock(l0, l1); + assert(false); + } + catch (int) + { + assert(!l0.locked()); + assert(!l1.locked()); + } + } + { + L2 l0; + L0 l1; + try + { + std::lock(l0, l1); + assert(false); + } + catch (int) + { + assert(!l0.locked()); + assert(!l1.locked()); + } + } + { + L1 l0; + L2 l1; + try + { + std::lock(l0, l1); + assert(false); + } + catch (int) + { + assert(!l0.locked()); + assert(!l1.locked()); + } + } + { + L2 l0; + L1 l1; + try + { + std::lock(l0, l1); + assert(false); + } + catch (int) + { + assert(!l0.locked()); + assert(!l1.locked()); + } + } + { + L2 l0; + L2 l1; + try + { + std::lock(l0, l1); + assert(false); + } + catch (int) + { + assert(!l0.locked()); + assert(!l1.locked()); + } + } +#ifndef _LIBCPP_HAS_NO_VARIADICS + { + L0 l0; + L0 l1; + L0 l2; + std::lock(l0, l1, l2); + assert(l0.locked()); + assert(l1.locked()); + assert(l2.locked()); + } + { + L2 l0; + L2 l1; + L2 l2; + try + { + std::lock(l0, l1, l2); + assert(false); + } + catch (int) + { + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + } + } + { + L0 l0; + L0 l1; + L1 l2; + std::lock(l0, l1, l2); + assert(l0.locked()); + assert(l1.locked()); + assert(l2.locked()); + } + { + L0 l0; + L1 l1; + L0 l2; + std::lock(l0, l1, l2); + assert(l0.locked()); + assert(l1.locked()); + assert(l2.locked()); + } + { + L1 l0; + L0 l1; + L0 l2; + std::lock(l0, l1, l2); + assert(l0.locked()); + assert(l1.locked()); + assert(l2.locked()); + } + { + L0 l0; + L0 l1; + L2 l2; + try + { + std::lock(l0, l1, l2); + assert(false); + } + catch (int) + { + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + } + } + { + L0 l0; + L2 l1; + L0 l2; + try + { + std::lock(l0, l1, l2); + assert(false); + } + catch (int) + { + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + } + } + { + L2 l0; + L0 l1; + L0 l2; + try + { + std::lock(l0, l1, l2); + assert(false); + } + catch (int) + { + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + } + } + { + L2 l0; + L2 l1; + L0 l2; + try + { + std::lock(l0, l1, l2); + assert(false); + } + catch (int) + { + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + } + } + { + L2 l0; + L0 l1; + L2 l2; + try + { + std::lock(l0, l1, l2); + assert(false); + } + catch (int) + { + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + } + } + { + L0 l0; + L2 l1; + L2 l2; + try + { + std::lock(l0, l1, l2); + assert(false); + } + catch (int) + { + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + } + } + { + L2 l0; + L2 l1; + L1 l2; + try + { + std::lock(l0, l1, l2); + assert(false); + } + catch (int) + { + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + } + } + { + L2 l0; + L1 l1; + L2 l2; + try + { + std::lock(l0, l1, l2); + assert(false); + } + catch (int) + { + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + } + } + { + L1 l0; + L2 l1; + L2 l2; + try + { + std::lock(l0, l1, l2); + assert(false); + } + catch (int) + { + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + } + } + { + L0 l0; + L0 l1; + L0 l2; + L0 l3; + std::lock(l0, l1, l2, l3); + assert(l0.locked()); + assert(l1.locked()); + assert(l2.locked()); + assert(l3.locked()); + } + { + L0 l0; + L0 l1; + L0 l2; + L1 l3; + std::lock(l0, l1, l2, l3); + assert(l0.locked()); + assert(l1.locked()); + assert(l2.locked()); + assert(l3.locked()); + } + { + L0 l0; + L0 l1; + L1 l2; + L0 l3; + std::lock(l0, l1, l2, l3); + assert(l0.locked()); + assert(l1.locked()); + assert(l2.locked()); + assert(l3.locked()); + } + { + L0 l0; + L1 l1; + L0 l2; + L0 l3; + std::lock(l0, l1, l2, l3); + assert(l0.locked()); + assert(l1.locked()); + assert(l2.locked()); + assert(l3.locked()); + } + { + L1 l0; + L0 l1; + L0 l2; + L0 l3; + std::lock(l0, l1, l2, l3); + assert(l0.locked()); + assert(l1.locked()); + assert(l2.locked()); + assert(l3.locked()); + } + { + L0 l0; + L0 l1; + L0 l2; + L2 l3; + try + { + std::lock(l0, l1, l2, l3); + assert(false); + } + catch (int) + { + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + assert(!l3.locked()); + } + } + { + L0 l0; + L0 l1; + L2 l2; + L0 l3; + try + { + std::lock(l0, l1, l2, l3); + assert(false); + } + catch (int) + { + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + assert(!l3.locked()); + } + } + { + L0 l0; + L2 l1; + L0 l2; + L0 l3; + try + { + std::lock(l0, l1, l2, l3); + assert(false); + } + catch (int) + { + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + assert(!l3.locked()); + } + } + { + L2 l0; + L0 l1; + L0 l2; + L0 l3; + try + { + std::lock(l0, l1, l2, l3); + assert(false); + } + catch (int) + { + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + assert(!l3.locked()); + } + } +#endif // _LIBCPP_HAS_NO_VARIADICS +} diff --git a/test/std/thread/thread.mutex/thread.lock.algorithm/try_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock.algorithm/try_lock.pass.cpp new file mode 100644 index 000000000000..f0c54b71883f --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock.algorithm/try_lock.pass.cpp @@ -0,0 +1,516 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <mutex> + +// template <class L1, class L2, class... L3> +// int try_lock(L1&, L2&, L3&...); + +#include <mutex> +#include <cassert> + +class L0 +{ + bool locked_; + +public: + L0() : locked_(false) {} + + bool try_lock() + { + locked_ = true; + return locked_; + } + + void unlock() {locked_ = false;} + + bool locked() const {return locked_;} +}; + +class L1 +{ + bool locked_; + +public: + L1() : locked_(false) {} + + bool try_lock() + { + locked_ = false; + return locked_; + } + + void unlock() {locked_ = false;} + + bool locked() const {return locked_;} +}; + +class L2 +{ + bool locked_; + +public: + L2() : locked_(false) {} + + bool try_lock() + { + throw 1; + return locked_; + } + + void unlock() {locked_ = false;} + + bool locked() const {return locked_;} +}; + +int main() +{ + { + L0 l0; + L0 l1; + assert(std::try_lock(l0, l1) == -1); + assert(l0.locked()); + assert(l1.locked()); + } + { + L0 l0; + L1 l1; + assert(std::try_lock(l0, l1) == 1); + assert(!l0.locked()); + assert(!l1.locked()); + } + { + L1 l0; + L0 l1; + assert(std::try_lock(l0, l1) == 0); + assert(!l0.locked()); + assert(!l1.locked()); + } + { + L0 l0; + L2 l1; + try + { + std::try_lock(l0, l1); + assert(false); + } + catch (int) + { + assert(!l0.locked()); + assert(!l1.locked()); + } + } + { + L2 l0; + L0 l1; + try + { + std::try_lock(l0, l1); + assert(false); + } + catch (int) + { + assert(!l0.locked()); + assert(!l1.locked()); + } + } +#ifndef _LIBCPP_HAS_NO_VARIADICS + { + L0 l0; + L0 l1; + L0 l2; + assert(std::try_lock(l0, l1, l2) == -1); + assert(l0.locked()); + assert(l1.locked()); + assert(l2.locked()); + } + { + L1 l0; + L1 l1; + L1 l2; + assert(std::try_lock(l0, l1, l2) == 0); + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + } + { + L2 l0; + L2 l1; + L2 l2; + try + { + std::try_lock(l0, l1, l2); + assert(false); + } + catch (int) + { + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + } + } + { + L0 l0; + L1 l1; + L2 l2; + assert(std::try_lock(l0, l1, l2) == 1); + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + } + { + L0 l0; + L0 l1; + L1 l2; + assert(std::try_lock(l0, l1, l2) == 2); + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + } + { + L0 l0; + L1 l1; + L0 l2; + assert(std::try_lock(l0, l1, l2) == 1); + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + } + { + L1 l0; + L0 l1; + L0 l2; + assert(std::try_lock(l0, l1, l2) == 0); + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + } + { + L0 l0; + L0 l1; + L2 l2; + try + { + std::try_lock(l0, l1, l2); + assert(false); + } + catch (int) + { + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + } + } + { + L0 l0; + L2 l1; + L0 l2; + try + { + std::try_lock(l0, l1, l2); + assert(false); + } + catch (int) + { + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + } + } + { + L2 l0; + L0 l1; + L0 l2; + try + { + std::try_lock(l0, l1, l2); + assert(false); + } + catch (int) + { + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + } + } + { + L1 l0; + L1 l1; + L0 l2; + assert(std::try_lock(l0, l1, l2) == 0); + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + } + { + L1 l0; + L0 l1; + L1 l2; + assert(std::try_lock(l0, l1, l2) == 0); + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + } + { + L0 l0; + L1 l1; + L1 l2; + assert(std::try_lock(l0, l1, l2) == 1); + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + } + { + L1 l0; + L1 l1; + L2 l2; + assert(std::try_lock(l0, l1, l2) == 0); + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + } + { + L1 l0; + L2 l1; + L1 l2; + assert(std::try_lock(l0, l1, l2) == 0); + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + } + { + L2 l0; + L1 l1; + L1 l2; + try + { + std::try_lock(l0, l1, l2); + assert(false); + } + catch (int) + { + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + } + } + { + L2 l0; + L2 l1; + L0 l2; + try + { + std::try_lock(l0, l1, l2); + assert(false); + } + catch (int) + { + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + } + } + { + L2 l0; + L0 l1; + L2 l2; + try + { + std::try_lock(l0, l1, l2); + assert(false); + } + catch (int) + { + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + } + } + { + L0 l0; + L2 l1; + L2 l2; + try + { + std::try_lock(l0, l1, l2); + assert(false); + } + catch (int) + { + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + } + } + { + L2 l0; + L2 l1; + L1 l2; + try + { + std::try_lock(l0, l1, l2); + assert(false); + } + catch (int) + { + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + } + } + { + L2 l0; + L1 l1; + L2 l2; + try + { + std::try_lock(l0, l1, l2); + assert(false); + } + catch (int) + { + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + } + } + { + L1 l0; + L2 l1; + L2 l2; + assert(std::try_lock(l0, l1, l2) == 0); + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + } + { + L0 l0; + L2 l1; + L1 l2; + try + { + std::try_lock(l0, l1, l2); + assert(false); + } + catch (int) + { + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + } + } + { + L1 l0; + L0 l1; + L2 l2; + assert(std::try_lock(l0, l1, l2) == 0); + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + } + { + L1 l0; + L2 l1; + L0 l2; + assert(std::try_lock(l0, l1, l2) == 0); + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + } + { + L2 l0; + L0 l1; + L1 l2; + try + { + std::try_lock(l0, l1, l2); + assert(false); + } + catch (int) + { + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + } + } + { + L2 l0; + L1 l1; + L0 l2; + try + { + std::try_lock(l0, l1, l2); + assert(false); + } + catch (int) + { + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + } + } + { + L0 l0; + L0 l1; + L0 l2; + L0 l3; + assert(std::try_lock(l0, l1, l2, l3) == -1); + assert(l0.locked()); + assert(l1.locked()); + assert(l2.locked()); + assert(l3.locked()); + } + { + L1 l0; + L0 l1; + L0 l2; + L0 l3; + assert(std::try_lock(l0, l1, l2, l3) == 0); + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + assert(!l3.locked()); + } + { + L0 l0; + L1 l1; + L0 l2; + L0 l3; + assert(std::try_lock(l0, l1, l2, l3) == 1); + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + assert(!l3.locked()); + } + { + L0 l0; + L0 l1; + L1 l2; + L0 l3; + assert(std::try_lock(l0, l1, l2, l3) == 2); + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + assert(!l3.locked()); + } + { + L0 l0; + L0 l1; + L0 l2; + L1 l3; + assert(std::try_lock(l0, l1, l2, l3) == 3); + assert(!l0.locked()); + assert(!l1.locked()); + assert(!l2.locked()); + assert(!l3.locked()); + } +#endif // _LIBCPP_HAS_NO_VARIADICS +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/adopt_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/adopt_lock.pass.cpp new file mode 100644 index 000000000000..83271009a67e --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/adopt_lock.pass.cpp @@ -0,0 +1,51 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <mutex> + +// template <class Mutex> class lock_guard; + +// lock_guard(mutex_type& m, adopt_lock_t); + +#include <mutex> +#include <thread> +#include <cstdlib> +#include <cassert> + +std::mutex m; + +typedef std::chrono::system_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef std::chrono::milliseconds ms; +typedef std::chrono::nanoseconds ns; + +void f() +{ + time_point t0 = Clock::now(); + time_point t1; + { + m.lock(); + std::lock_guard<std::mutex> lg(m, std::adopt_lock); + t1 = Clock::now(); + } + ns d = t1 - t0 - ms(250); + assert(d < ms(50)); // within 50ms +} + +int main() +{ + m.lock(); + std::thread t(f); + std::this_thread::sleep_for(ms(250)); + m.unlock(); + t.join(); +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/assign.fail.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/assign.fail.cpp new file mode 100644 index 000000000000..53abb42c0e38 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/assign.fail.cpp @@ -0,0 +1,25 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// <mutex> + +// template <class Mutex> class lock_guard; + +// lock_guard& operator=(lock_guard const&) = delete; + +#include <mutex> + +int main() +{ + std::mutex m0; + std::mutex m1; + std::lock_guard<std::mutex> lg0(m0); + std::lock_guard<std::mutex> lg(m1); + lg = lg0; +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/copy.fail.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/copy.fail.cpp new file mode 100644 index 000000000000..296ccdaee67a --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/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. +// +//===----------------------------------------------------------------------===// + +// <mutex> + +// template <class Mutex> class lock_guard; + +// lock_guard(lock_guard const&) = delete; + +#include <mutex> + +int main() +{ + std::mutex m; + std::lock_guard<std::mutex> lg0(m); + std::lock_guard<std::mutex> lg(lg0); +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.fail.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.fail.cpp new file mode 100644 index 000000000000..246eb935c995 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.fail.cpp @@ -0,0 +1,48 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// <mutex> + +// template <class Mutex> class lock_guard; + +// explicit lock_guard(mutex_type& m); + +#include <mutex> +#include <thread> +#include <cstdlib> +#include <cassert> + +std::mutex m; + +typedef std::chrono::system_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef std::chrono::milliseconds ms; +typedef std::chrono::nanoseconds ns; + +void f() +{ + time_point t0 = Clock::now(); + time_point t1; + { + std::lock_guard<std::mutex> lg = m; + t1 = Clock::now(); + } + ns d = t1 - t0 - ms(250); + assert(d < ns(2500000)); // within 2.5ms +} + +int main() +{ + m.lock(); + std::thread t(f); + std::this_thread::sleep_for(ms(250)); + m.unlock(); + t.join(); +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp new file mode 100644 index 000000000000..a15405fcd98b --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp @@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <mutex> + +// template <class Mutex> class lock_guard; + +// explicit lock_guard(mutex_type& m); + +#include <mutex> +#include <thread> +#include <cstdlib> +#include <cassert> + +std::mutex m; + +typedef std::chrono::system_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef std::chrono::milliseconds ms; +typedef std::chrono::nanoseconds ns; + +void f() +{ + time_point t0 = Clock::now(); + time_point t1; + { + std::lock_guard<std::mutex> lg(m); + t1 = Clock::now(); + } + ns d = t1 - t0 - ms(250); + assert(d < ms(200)); // within 200ms +} + +int main() +{ + m.lock(); + std::thread t(f); + std::this_thread::sleep_for(ms(250)); + m.unlock(); + t.join(); +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/types.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/types.pass.cpp new file mode 100644 index 000000000000..5238ed67064f --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/types.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 + +// <mutex> + +// template <class Mutex> +// class lock_guard +// { +// public: +// typedef Mutex mutex_type; +// ... +// }; + +#include <mutex> +#include <type_traits> + +int main() +{ + static_assert((std::is_same<std::lock_guard<std::mutex>::mutex_type, + std::mutex>::value), ""); +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/copy_assign.fail.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/copy_assign.fail.cpp new file mode 100644 index 000000000000..446807f3f333 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/copy_assign.fail.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// <shared_mutex> + +// template <class Mutex> class shared_lock; + +// shared_lock& operator=(shared_lock const&) = delete; + +#include <shared_mutex> + +#if _LIBCPP_STD_VER > 11 + +std::shared_timed_mutex m0; +std::shared_timed_mutex m1; + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + std::shared_lock<std::shared_timed_mutex> lk0(m0); + std::shared_lock<std::shared_timed_mutex> lk1(m1); + lk1 = lk0; +#else +# error +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/copy_ctor.fail.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/copy_ctor.fail.cpp new file mode 100644 index 000000000000..370c1fa4e336 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/copy_ctor.fail.cpp @@ -0,0 +1,30 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// <shared_mutex> + +// template <class Mutex> class shared_lock; + +// shared_lock(shared_lock const&) = delete; + +#include <shared_mutex> + +#if _LIBCPP_STD_VER > 11 +std::shared_timed_mutex m; +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + std::shared_lock<std::shared_timed_mutex> lk0(m); + std::shared_lock<std::shared_timed_mutex> lk = lk0; +#else +# error +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/default.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/default.pass.cpp new file mode 100644 index 000000000000..2c1c665fdeda --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/default.pass.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <shared_mutex> + +// template <class Mutex> class shared_lock; + +// shared_lock(); + +#include <shared_mutex> +#include <cassert> + +int main() +{ +#if _LIBCPP_STD_VER > 11 + std::shared_lock<std::shared_timed_mutex> ul; + assert(!ul.owns_lock()); + assert(ul.mutex() == nullptr); +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_assign.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_assign.pass.cpp new file mode 100644 index 000000000000..8676f2ca0472 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_assign.pass.cpp @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <shared_mutex> + +// template <class Mutex> class shared_lock; + +// shared_lock& operator=(shared_lock&& u); + +#include <shared_mutex> +#include <cassert> + +#if _LIBCPP_STD_VER > 11 + +std::shared_timed_mutex m0; +std::shared_timed_mutex m1; + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + std::shared_lock<std::shared_timed_mutex> lk0(m0); + std::shared_lock<std::shared_timed_mutex> lk1(m1); + lk1 = std::move(lk0); + assert(lk1.mutex() == &m0); + assert(lk1.owns_lock() == true); + assert(lk0.mutex() == nullptr); + assert(lk0.owns_lock() == false); +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_ctor.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_ctor.pass.cpp new file mode 100644 index 000000000000..f59d2e826980 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_ctor.pass.cpp @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <shared_mutex> + +// template <class Mutex> class shared_lock; + +// shared_lock(shared_lock&& u); + +#include <shared_mutex> +#include <cassert> + +#if _LIBCPP_STD_VER > 11 +std::shared_timed_mutex m; +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + std::shared_lock<std::shared_timed_mutex> lk0(m); + std::shared_lock<std::shared_timed_mutex> lk = std::move(lk0); + assert(lk.mutex() == &m); + assert(lk.owns_lock() == true); + assert(lk0.mutex() == nullptr); + assert(lk0.owns_lock() == false); +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex.pass.cpp new file mode 100644 index 000000000000..c8a0287314bf --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex.pass.cpp @@ -0,0 +1,81 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <shared_mutex> + +// template <class Mutex> class shared_lock; + +// explicit shared_lock(mutex_type& m); + +#include <shared_mutex> +#include <thread> +#include <vector> +#include <cstdlib> +#include <cassert> + +#if _LIBCPP_STD_VER > 11 + +std::shared_timed_mutex m; + +typedef std::chrono::system_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef std::chrono::milliseconds ms; +typedef std::chrono::nanoseconds ns; + +void f() +{ + time_point t0 = Clock::now(); + time_point t1; + { + std::shared_lock<std::shared_timed_mutex> ul(m); + t1 = Clock::now(); + } + ns d = t1 - t0 - ms(250); + assert(d < ms(50)); // within 50ms +} + +void g() +{ + time_point t0 = Clock::now(); + time_point t1; + { + std::shared_lock<std::shared_timed_mutex> ul(m); + t1 = Clock::now(); + } + ns d = t1 - t0; + assert(d < ms(50)); // within 50ms +} + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + m.lock(); + std::vector<std::thread> v; + for (int i = 0; i < 5; ++i) + v.push_back(std::thread(f)); + std::this_thread::sleep_for(ms(250)); + m.unlock(); + for (auto& t : v) + t.join(); + m.lock_shared(); + for (auto& t : v) + t = std::thread(g); + std::thread q(f); + std::this_thread::sleep_for(ms(250)); + m.unlock_shared(); + for (auto& t : v) + t.join(); + q.join(); +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_adopt_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_adopt_lock.pass.cpp new file mode 100644 index 000000000000..3b49b3029052 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_adopt_lock.pass.cpp @@ -0,0 +1,30 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <shared_mutex> + +// template <class Mutex> class shared_lock; + +// shared_lock(mutex_type& m, adopt_lock_t); + +#include <shared_mutex> +#include <cassert> + +int main() +{ +#if _LIBCPP_STD_VER > 11 + std::shared_timed_mutex m; + m.lock_shared(); + std::shared_lock<std::shared_timed_mutex> lk(m, std::adopt_lock); + assert(lk.mutex() == &m); + assert(lk.owns_lock() == true); +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_defer_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_defer_lock.pass.cpp new file mode 100644 index 000000000000..bbc38fcadb10 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_defer_lock.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 + +// <shared_mutex> + +// template <class Mutex> class shared_lock; + +// shared_lock(mutex_type& m, defer_lock_t); + +#include <shared_mutex> +#include <cassert> + +int main() +{ +#if _LIBCPP_STD_VER > 11 + std::shared_timed_mutex m; + std::shared_lock<std::shared_timed_mutex> lk(m, std::defer_lock); + assert(lk.mutex() == &m); + assert(lk.owns_lock() == false); +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_duration.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_duration.pass.cpp new file mode 100644 index 000000000000..9816e57f692a --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_duration.pass.cpp @@ -0,0 +1,81 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <shared_mutex> + +// class timed_mutex; + +// template <class Rep, class Period> +// shared_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time); + +#include <shared_mutex> +#include <thread> +#include <vector> +#include <cstdlib> +#include <cassert> + +#if _LIBCPP_STD_VER > 11 + +std::shared_timed_mutex m; + +typedef std::chrono::steady_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef std::chrono::milliseconds ms; +typedef std::chrono::nanoseconds ns; + +void f1() +{ + time_point t0 = Clock::now(); + std::shared_lock<std::shared_timed_mutex> lk(m, ms(300)); + assert(lk.owns_lock() == true); + time_point t1 = Clock::now(); + ns d = t1 - t0 - ms(250); + assert(d < ms(50)); // within 50ms +} + +void f2() +{ + time_point t0 = Clock::now(); + std::shared_lock<std::shared_timed_mutex> lk(m, ms(250)); + assert(lk.owns_lock() == false); + time_point t1 = Clock::now(); + ns d = t1 - t0 - ms(250); + assert(d < ms(50)); // within 50ms +} + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + { + m.lock(); + std::vector<std::thread> v; + for (int i = 0; i < 5; ++i) + v.push_back(std::thread(f1)); + std::this_thread::sleep_for(ms(250)); + m.unlock(); + for (auto& t : v) + t.join(); + } + { + m.lock(); + std::vector<std::thread> v; + for (int i = 0; i < 5; ++i) + v.push_back(std::thread(f2)); + std::this_thread::sleep_for(ms(300)); + m.unlock(); + for (auto& t : v) + t.join(); + } +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_time_point.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_time_point.pass.cpp new file mode 100644 index 000000000000..5d188ab06737 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_time_point.pass.cpp @@ -0,0 +1,81 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <shared_mutex> + +// class shared_timed_mutex; + +// template <class Clock, class Duration> +// shared_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time); + +#include <shared_mutex> +#include <thread> +#include <vector> +#include <cstdlib> +#include <cassert> + +#if _LIBCPP_STD_VER > 11 + +std::shared_timed_mutex m; + +typedef std::chrono::steady_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef std::chrono::milliseconds ms; +typedef std::chrono::nanoseconds ns; + +void f1() +{ + time_point t0 = Clock::now(); + std::shared_lock<std::shared_timed_mutex> lk(m, Clock::now() + ms(300)); + assert(lk.owns_lock() == true); + time_point t1 = Clock::now(); + ns d = t1 - t0 - ms(250); + assert(d < ns(50000000)); // within 50ms +} + +void f2() +{ + time_point t0 = Clock::now(); + std::shared_lock<std::shared_timed_mutex> lk(m, Clock::now() + ms(250)); + assert(lk.owns_lock() == false); + time_point t1 = Clock::now(); + ns d = t1 - t0 - ms(250); + assert(d < ms(50)); // within 50ms +} + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + { + m.lock(); + std::vector<std::thread> v; + for (int i = 0; i < 5; ++i) + v.push_back(std::thread(f1)); + std::this_thread::sleep_for(ms(250)); + m.unlock(); + for (auto& t : v) + t.join(); + } + { + m.lock(); + std::vector<std::thread> v; + for (int i = 0; i < 5; ++i) + v.push_back(std::thread(f2)); + std::this_thread::sleep_for(ms(300)); + m.unlock(); + for (auto& t : v) + t.join(); + } +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_try_to_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_try_to_lock.pass.cpp new file mode 100644 index 000000000000..f2d4e0deb73f --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_try_to_lock.pass.cpp @@ -0,0 +1,74 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <shared_mutex> + +// template <class Mutex> class shared_lock; + +// shared_lock(mutex_type& m, try_to_lock_t); + +#include <shared_mutex> +#include <thread> +#include <vector> +#include <cstdlib> +#include <cassert> + +#if _LIBCPP_STD_VER > 11 + +std::shared_timed_mutex m; + +typedef std::chrono::system_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef std::chrono::milliseconds ms; +typedef std::chrono::nanoseconds ns; + +void f() +{ + time_point t0 = Clock::now(); + { + std::shared_lock<std::shared_timed_mutex> lk(m, std::try_to_lock); + assert(lk.owns_lock() == false); + } + { + std::shared_lock<std::shared_timed_mutex> lk(m, std::try_to_lock); + assert(lk.owns_lock() == false); + } + { + std::shared_lock<std::shared_timed_mutex> lk(m, std::try_to_lock); + assert(lk.owns_lock() == false); + } + while (true) + { + std::shared_lock<std::shared_timed_mutex> lk(m, std::try_to_lock); + if (lk.owns_lock()) + break; + } + time_point t1 = Clock::now(); + ns d = t1 - t0 - ms(250); + assert(d < ms(200)); // within 200ms +} + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + m.lock(); + std::vector<std::thread> v; + for (int i = 0; i < 5; ++i) + v.push_back(std::thread(f)); + std::this_thread::sleep_for(ms(250)); + m.unlock(); + for (auto& t : v) + t.join(); +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/lock.pass.cpp new file mode 100644 index 000000000000..f1500652badd --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/lock.pass.cpp @@ -0,0 +1,79 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <shared_mutex> + +// template <class Mutex> class shared_lock; + +// void lock(); + +#include <shared_mutex> +#include <thread> +#include <vector> +#include <cstdlib> +#include <cassert> + +#if _LIBCPP_STD_VER > 11 + +std::shared_timed_mutex m; + +typedef std::chrono::system_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef std::chrono::milliseconds ms; +typedef std::chrono::nanoseconds ns; + +void f() +{ + std::shared_lock<std::shared_timed_mutex> lk(m, std::defer_lock); + time_point t0 = Clock::now(); + lk.lock(); + time_point t1 = Clock::now(); + assert(lk.owns_lock() == true); + ns d = t1 - t0 - ms(250); + assert(d < ms(25)); // within 25ms + try + { + lk.lock(); + assert(false); + } + catch (std::system_error& e) + { + assert(e.code().value() == EDEADLK); + } + lk.unlock(); + lk.release(); + try + { + lk.lock(); + assert(false); + } + catch (std::system_error& e) + { + assert(e.code().value() == EPERM); + } +} + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + m.lock(); + std::vector<std::thread> v; + for (int i = 0; i < 5; ++i) + v.push_back(std::thread(f)); + std::this_thread::sleep_for(ms(250)); + m.unlock(); + for (auto& t : v) + t.join(); +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock.pass.cpp new file mode 100644 index 000000000000..82b1ff865053 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock.pass.cpp @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <shared_mutex> + +// template <class Mutex> class shared_lock; + +// bool try_lock(); + +#include <shared_mutex> +#include <cassert> + +#if _LIBCPP_STD_VER > 11 + +bool try_lock_called = false; + +struct mutex +{ + bool try_lock_shared() + { + try_lock_called = !try_lock_called; + return try_lock_called; + } + void unlock_shared() {} +}; + +mutex m; + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + std::shared_lock<mutex> lk(m, std::defer_lock); + assert(lk.try_lock() == true); + assert(try_lock_called == true); + assert(lk.owns_lock() == true); + try + { + lk.try_lock(); + assert(false); + } + catch (std::system_error& e) + { + assert(e.code().value() == EDEADLK); + } + lk.unlock(); + assert(lk.try_lock() == false); + assert(try_lock_called == false); + assert(lk.owns_lock() == false); + lk.release(); + try + { + lk.try_lock(); + assert(false); + } + catch (std::system_error& e) + { + assert(e.code().value() == EPERM); + } +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_for.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_for.pass.cpp new file mode 100644 index 000000000000..5867465a6626 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_for.pass.cpp @@ -0,0 +1,75 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <shared_mutex> + +// template <class Mutex> class shared_lock; + +// template <class Rep, class Period> +// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); + +#include <shared_mutex> +#include <cassert> + +#if _LIBCPP_STD_VER > 11 + +bool try_lock_for_called = false; + +typedef std::chrono::milliseconds ms; + +struct mutex +{ + template <class Rep, class Period> + bool try_lock_shared_for(const std::chrono::duration<Rep, Period>& rel_time) + { + assert(rel_time == ms(5)); + try_lock_for_called = !try_lock_for_called; + return try_lock_for_called; + } + void unlock_shared() {} +}; + +mutex m; + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + std::shared_lock<mutex> lk(m, std::defer_lock); + assert(lk.try_lock_for(ms(5)) == true); + assert(try_lock_for_called == true); + assert(lk.owns_lock() == true); + try + { + lk.try_lock_for(ms(5)); + assert(false); + } + catch (std::system_error& e) + { + assert(e.code().value() == EDEADLK); + } + lk.unlock(); + assert(lk.try_lock_for(ms(5)) == false); + assert(try_lock_for_called == false); + assert(lk.owns_lock() == false); + lk.release(); + try + { + lk.try_lock_for(ms(5)); + assert(false); + } + catch (std::system_error& e) + { + assert(e.code().value() == EPERM); + } +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_until.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_until.pass.cpp new file mode 100644 index 000000000000..9d38983be724 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_until.pass.cpp @@ -0,0 +1,75 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <shared_mutex> + +// template <class Mutex> class shared_lock; + +// template <class Clock, class Duration> +// bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time); + +#include <shared_mutex> +#include <cassert> + +#if _LIBCPP_STD_VER > 11 + +bool try_lock_until_called = false; + +struct mutex +{ + template <class Clock, class Duration> + bool try_lock_shared_until(const std::chrono::time_point<Clock, Duration>& abs_time) + { + typedef std::chrono::milliseconds ms; + assert(Clock::now() - abs_time < ms(5)); + try_lock_until_called = !try_lock_until_called; + return try_lock_until_called; + } + void unlock_shared() {} +}; + +mutex m; + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + typedef std::chrono::steady_clock Clock; + std::shared_lock<mutex> lk(m, std::defer_lock); + assert(lk.try_lock_until(Clock::now()) == true); + assert(try_lock_until_called == true); + assert(lk.owns_lock() == true); + try + { + lk.try_lock_until(Clock::now()); + assert(false); + } + catch (std::system_error& e) + { + assert(e.code().value() == EDEADLK); + } + lk.unlock(); + assert(lk.try_lock_until(Clock::now()) == false); + assert(try_lock_until_called == false); + assert(lk.owns_lock() == false); + lk.release(); + try + { + lk.try_lock_until(Clock::now()); + assert(false); + } + catch (std::system_error& e) + { + assert(e.code().value() == EPERM); + } +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/unlock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/unlock.pass.cpp new file mode 100644 index 000000000000..eb08a45cde6e --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/unlock.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 + +// <shared_mutex> + +// template <class Mutex> class shared_lock; + +// void unlock(); + +#include <shared_mutex> +#include <cassert> + +#if _LIBCPP_STD_VER > 11 + +bool unlock_called = false; + +struct mutex +{ + void lock_shared() {} + void unlock_shared() {unlock_called = true;} +}; + +mutex m; + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + std::shared_lock<mutex> lk(m); + lk.unlock(); + assert(unlock_called == true); + assert(lk.owns_lock() == false); + try + { + lk.unlock(); + assert(false); + } + catch (std::system_error& e) + { + assert(e.code().value() == EPERM); + } + lk.release(); + try + { + lk.unlock(); + assert(false); + } + catch (std::system_error& e) + { + assert(e.code().value() == EPERM); + } +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/member_swap.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/member_swap.pass.cpp new file mode 100644 index 000000000000..8505763e44bc --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/member_swap.pass.cpp @@ -0,0 +1,45 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <shared_mutex> + +// template <class Mutex> class shared_lock; + +// void swap(shared_lock& u) noexcept; + +#include <shared_mutex> +#include <cassert> + +#if _LIBCPP_STD_VER > 11 + +struct mutex +{ + void lock_shared() {} + void unlock_shared() {} +}; + +mutex m; + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + std::shared_lock<mutex> lk1(m); + std::shared_lock<mutex> lk2; + lk1.swap(lk2); + assert(lk1.mutex() == nullptr); + assert(lk1.owns_lock() == false); + assert(lk2.mutex() == &m); + assert(lk2.owns_lock() == true); + static_assert(noexcept(lk1.swap(lk2)), "member swap must be noexcept"); +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/nonmember_swap.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/nonmember_swap.pass.cpp new file mode 100644 index 000000000000..057dbc4cd3b7 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/nonmember_swap.pass.cpp @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <shared_mutex> + +// template <class Mutex> class shared_lock; + +// template <class Mutex> +// void swap(shared_lock<Mutex>& x, shared_lock<Mutex>& y) noexcept; + +#include <shared_mutex> +#include <cassert> + +#if _LIBCPP_STD_VER > 11 + +struct mutex +{ + void lock_shared() {} + void unlock_shared() {} +}; + +mutex m; + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + std::shared_lock<mutex> lk1(m); + std::shared_lock<mutex> lk2; + swap(lk1, lk2); + assert(lk1.mutex() == nullptr); + assert(lk1.owns_lock() == false); + assert(lk2.mutex() == &m); + assert(lk2.owns_lock() == true); + static_assert(noexcept(swap(lk1, lk2)), "non-member swap must be noexcept"); +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/release.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/release.pass.cpp new file mode 100644 index 000000000000..65ddca624725 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/release.pass.cpp @@ -0,0 +1,53 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <shared_mutex> + +// template <class Mutex> class shared_lock; + +// mutex_type* release() noexcept; + +#include <shared_mutex> +#include <cassert> + +#if _LIBCPP_STD_VER > 11 + +struct mutex +{ + static int lock_count; + static int unlock_count; + void lock_shared() {++lock_count;} + void unlock_shared() {++unlock_count;} +}; + +int mutex::lock_count = 0; +int mutex::unlock_count = 0; + +mutex m; + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + std::shared_lock<mutex> lk(m); + assert(lk.mutex() == &m); + assert(lk.owns_lock() == true); + assert(mutex::lock_count == 1); + assert(mutex::unlock_count == 0); + assert(lk.release() == &m); + assert(lk.mutex() == nullptr); + assert(lk.owns_lock() == false); + assert(mutex::lock_count == 1); + assert(mutex::unlock_count == 0); + static_assert(noexcept(lk.release()), "release must be noexcept"); +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/mutex.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/mutex.pass.cpp new file mode 100644 index 000000000000..4eb75d8f050e --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/mutex.pass.cpp @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <shared_mutex> + +// template <class Mutex> class shared_lock; + +// mutex_type *mutex() const noexcept; + +#include <shared_mutex> +#include <cassert> + +#if _LIBCPP_STD_VER > 11 + +std::shared_timed_mutex m; + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + std::shared_lock<std::shared_timed_mutex> lk0; + assert(lk0.mutex() == nullptr); + std::shared_lock<std::shared_timed_mutex> lk1(m); + assert(lk1.mutex() == &m); + lk1.unlock(); + assert(lk1.mutex() == &m); + static_assert(noexcept(lk0.mutex()), "mutex() must be noexcept"); +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/op_bool.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/op_bool.pass.cpp new file mode 100644 index 000000000000..d079d2d8b03a --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/op_bool.pass.cpp @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <shared_mutex> + +// template <class Mutex> class shared_lock; + +// explicit operator bool() const noexcept; + +#include <shared_mutex> +#include <cassert> + +#if _LIBCPP_STD_VER > 11 + +std::shared_timed_mutex m; + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + std::shared_lock<std::shared_timed_mutex> lk0; + assert(static_cast<bool>(lk0) == false); + std::shared_lock<std::shared_timed_mutex> lk1(m); + assert(static_cast<bool>(lk1) == true); + lk1.unlock(); + assert(static_cast<bool>(lk1) == false); + static_assert(noexcept(static_cast<bool>(lk0)), "explicit operator bool() must be noexcept"); +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/owns_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/owns_lock.pass.cpp new file mode 100644 index 000000000000..d64b0aa6a736 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/owns_lock.pass.cpp @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <shared_mutex> + +// template <class Mutex> class shared_lock; + +// bool owns_lock() const noexcept; + +#include <shared_mutex> +#include <cassert> + +#if _LIBCPP_STD_VER > 11 + +std::shared_timed_mutex m; + +#endif // _LIBCPP_STD_VER > 11 + +int main() +{ +#if _LIBCPP_STD_VER > 11 + std::shared_lock<std::shared_timed_mutex> lk0; + assert(lk0.owns_lock() == false); + std::shared_lock<std::shared_timed_mutex> lk1(m); + assert(lk1.owns_lock() == true); + lk1.unlock(); + assert(lk1.owns_lock() == false); + static_assert(noexcept(lk0.owns_lock()), "owns_lock must be noexcept"); +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/types.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/types.pass.cpp new file mode 100644 index 000000000000..c153b455f404 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/types.pass.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <shared_mutex> + +// template <class Mutex> +// class shared_lock +// { +// public: +// typedef Mutex mutex_type; +// ... +// }; + +#include <shared_mutex> +#include <type_traits> + +int main() +{ +#if _LIBCPP_STD_VER > 11 + static_assert((std::is_same<std::shared_lock<std::mutex>::mutex_type, + std::mutex>::value), ""); +#endif // _LIBCPP_STD_VER > 11 +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_assign.fail.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_assign.fail.cpp new file mode 100644 index 000000000000..4f477449d6a2 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_assign.fail.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// <mutex> + +// template <class Mutex> class unique_lock; + +// unique_lock& operator=(unique_lock const&) = delete; + +#include <mutex> +#include <cassert> + +std::mutex m0; +std::mutex m1; + +int main() +{ + std::unique_lock<std::mutex> lk0(m0); + std::unique_lock<std::mutex> lk1(m1); + lk1 = lk0; + assert(lk1.mutex() == &m0); + assert(lk1.owns_lock() == true); + assert(lk0.mutex() == nullptr); + assert(lk0.owns_lock() == false); +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_ctor.fail.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_ctor.fail.cpp new file mode 100644 index 000000000000..4888fe90d92c --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_ctor.fail.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. +// +//===----------------------------------------------------------------------===// + +// <mutex> + +// template <class Mutex> class unique_lock; + +// unique_lock(unique_lock const&) = delete; + +#include <mutex> +#include <cassert> + +std::mutex m; + +int main() +{ + std::unique_lock<std::mutex> lk0(m); + std::unique_lock<std::mutex> lk = lk0; + assert(lk.mutex() == &m); + assert(lk.owns_lock() == true); + assert(lk0.mutex() == nullptr); + assert(lk0.owns_lock() == false); +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/default.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/default.pass.cpp new file mode 100644 index 000000000000..a49bc507171c --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/default.pass.cpp @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <mutex> + +// template <class Mutex> class unique_lock; + +// unique_lock(); + +#include <mutex> +#include <cassert> + +int main() +{ + std::unique_lock<std::mutex> ul; + assert(!ul.owns_lock()); + assert(ul.mutex() == nullptr); +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_assign.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_assign.pass.cpp new file mode 100644 index 000000000000..4dff853088ac --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_assign.pass.cpp @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <mutex> + +// template <class Mutex> class unique_lock; + +// unique_lock& operator=(unique_lock&& u); + +#include <mutex> +#include <cassert> + +std::mutex m0; +std::mutex m1; + +int main() +{ +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + std::unique_lock<std::mutex> lk0(m0); + std::unique_lock<std::mutex> lk1(m1); + lk1 = std::move(lk0); + assert(lk1.mutex() == &m0); + assert(lk1.owns_lock() == true); + assert(lk0.mutex() == nullptr); + assert(lk0.owns_lock() == false); +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_ctor.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_ctor.pass.cpp new file mode 100644 index 000000000000..aa640ee6d746 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_ctor.pass.cpp @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <mutex> + +// template <class Mutex> class unique_lock; + +// unique_lock(unique_lock&& u); + +#include <mutex> +#include <cassert> + +std::mutex m; + +int main() +{ +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + std::unique_lock<std::mutex> lk0(m); + std::unique_lock<std::mutex> lk = std::move(lk0); + assert(lk.mutex() == &m); + assert(lk.owns_lock() == true); + assert(lk0.mutex() == nullptr); + assert(lk0.owns_lock() == false); +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex.pass.cpp new file mode 100644 index 000000000000..1f7217a8300e --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex.pass.cpp @@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <mutex> + +// template <class Mutex> class unique_lock; + +// explicit unique_lock(mutex_type& m); + +#include <mutex> +#include <thread> +#include <cstdlib> +#include <cassert> + +std::mutex m; + +typedef std::chrono::system_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef std::chrono::milliseconds ms; +typedef std::chrono::nanoseconds ns; + +void f() +{ + time_point t0 = Clock::now(); + time_point t1; + { + std::unique_lock<std::mutex> ul(m); + t1 = Clock::now(); + } + ns d = t1 - t0 - ms(250); + assert(d < ms(50)); // within 50ms +} + +int main() +{ + m.lock(); + std::thread t(f); + std::this_thread::sleep_for(ms(250)); + m.unlock(); + t.join(); +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_adopt_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_adopt_lock.pass.cpp new file mode 100644 index 000000000000..9c3a7b6505a4 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_adopt_lock.pass.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <mutex> + +// template <class Mutex> class unique_lock; + +// unique_lock(mutex_type& m, adopt_lock_t); + +#include <mutex> +#include <cassert> + +int main() +{ + std::mutex m; + m.lock(); + std::unique_lock<std::mutex> lk(m, std::adopt_lock); + assert(lk.mutex() == &m); + assert(lk.owns_lock() == true); +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_defer_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_defer_lock.pass.cpp new file mode 100644 index 000000000000..bf622311f013 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_defer_lock.pass.cpp @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <mutex> + +// template <class Mutex> class unique_lock; + +// unique_lock(mutex_type& m, defer_lock_t); + +#include <mutex> +#include <cassert> + +int main() +{ + std::mutex m; + std::unique_lock<std::mutex> lk(m, std::defer_lock); + assert(lk.mutex() == &m); + assert(lk.owns_lock() == false); +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_duration.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_duration.pass.cpp new file mode 100644 index 000000000000..33e400b0da80 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_duration.pass.cpp @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <mutex> + +// class timed_mutex; + +// template <class Rep, class Period> +// unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time); + +#include <mutex> +#include <thread> +#include <cstdlib> +#include <cassert> + +std::timed_mutex m; + +typedef std::chrono::steady_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef std::chrono::milliseconds ms; +typedef std::chrono::nanoseconds ns; + +void f1() +{ + time_point t0 = Clock::now(); + std::unique_lock<std::timed_mutex> lk(m, ms(300)); + assert(lk.owns_lock() == true); + time_point t1 = Clock::now(); + ns d = t1 - t0 - ms(250); + assert(d < ms(50)); // within 50ms +} + +void f2() +{ + time_point t0 = Clock::now(); + std::unique_lock<std::timed_mutex> lk(m, ms(250)); + assert(lk.owns_lock() == false); + time_point t1 = Clock::now(); + ns d = t1 - t0 - ms(250); + assert(d < ms(50)); // within 50ms +} + +int main() +{ + { + m.lock(); + std::thread t(f1); + std::this_thread::sleep_for(ms(250)); + m.unlock(); + t.join(); + } + { + m.lock(); + std::thread t(f2); + std::this_thread::sleep_for(ms(300)); + m.unlock(); + t.join(); + } +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_time_point.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_time_point.pass.cpp new file mode 100644 index 000000000000..2ead67097730 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_time_point.pass.cpp @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <mutex> + +// class timed_mutex; + +// template <class Clock, class Duration> +// unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time); + +#include <mutex> +#include <thread> +#include <cstdlib> +#include <cassert> + +std::timed_mutex m; + +typedef std::chrono::steady_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef std::chrono::milliseconds ms; +typedef std::chrono::nanoseconds ns; + +void f1() +{ + time_point t0 = Clock::now(); + std::unique_lock<std::timed_mutex> lk(m, Clock::now() + ms(300)); + assert(lk.owns_lock() == true); + time_point t1 = Clock::now(); + ns d = t1 - t0 - ms(250); + assert(d < ns(50000000)); // within 50ms +} + +void f2() +{ + time_point t0 = Clock::now(); + std::unique_lock<std::timed_mutex> lk(m, Clock::now() + ms(250)); + assert(lk.owns_lock() == false); + time_point t1 = Clock::now(); + ns d = t1 - t0 - ms(250); + assert(d < ms(50)); // within 50ms +} + +int main() +{ + { + m.lock(); + std::thread t(f1); + std::this_thread::sleep_for(ms(250)); + m.unlock(); + t.join(); + } + { + m.lock(); + std::thread t(f2); + std::this_thread::sleep_for(ms(300)); + m.unlock(); + t.join(); + } +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_try_to_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_try_to_lock.pass.cpp new file mode 100644 index 000000000000..cea58c554a9b --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_try_to_lock.pass.cpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <mutex> + +// template <class Mutex> class unique_lock; + +// unique_lock(mutex_type& m, try_to_lock_t); + +#include <mutex> +#include <thread> +#include <cstdlib> +#include <cassert> + +std::mutex m; + +typedef std::chrono::system_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef std::chrono::milliseconds ms; +typedef std::chrono::nanoseconds ns; + +void f() +{ + time_point t0 = Clock::now(); + { + std::unique_lock<std::mutex> lk(m, std::try_to_lock); + assert(lk.owns_lock() == false); + } + { + std::unique_lock<std::mutex> lk(m, std::try_to_lock); + assert(lk.owns_lock() == false); + } + { + std::unique_lock<std::mutex> lk(m, std::try_to_lock); + assert(lk.owns_lock() == false); + } + while (true) + { + std::unique_lock<std::mutex> lk(m, std::try_to_lock); + if (lk.owns_lock()) + break; + } + time_point t1 = Clock::now(); + ns d = t1 - t0 - ms(250); + assert(d < ms(200)); // within 200ms +} + +int main() +{ + m.lock(); + std::thread t(f); + std::this_thread::sleep_for(ms(250)); + m.unlock(); + t.join(); +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/lock.pass.cpp new file mode 100644 index 000000000000..f5408df98199 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/lock.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 + +// <mutex> + +// template <class Mutex> class unique_lock; + +// void lock(); + +#include <mutex> +#include <thread> +#include <cstdlib> +#include <cassert> + +std::mutex m; + +typedef std::chrono::system_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef std::chrono::milliseconds ms; +typedef std::chrono::nanoseconds ns; + +void f() +{ + std::unique_lock<std::mutex> lk(m, std::defer_lock); + time_point t0 = Clock::now(); + lk.lock(); + time_point t1 = Clock::now(); + assert(lk.owns_lock() == true); + ns d = t1 - t0 - ms(250); + assert(d < ms(25)); // within 25ms + try + { + lk.lock(); + assert(false); + } + catch (std::system_error& e) + { + assert(e.code().value() == EDEADLK); + } + lk.unlock(); + lk.release(); + try + { + lk.lock(); + assert(false); + } + catch (std::system_error& e) + { + assert(e.code().value() == EPERM); + } +} + +int main() +{ + m.lock(); + std::thread t(f); + std::this_thread::sleep_for(ms(250)); + m.unlock(); + t.join(); +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock.pass.cpp new file mode 100644 index 000000000000..bd88577f0a22 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock.pass.cpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <mutex> + +// template <class Mutex> class unique_lock; + +// bool try_lock(); + +#include <mutex> +#include <cassert> + +bool try_lock_called = false; + +struct mutex +{ + bool try_lock() + { + try_lock_called = !try_lock_called; + return try_lock_called; + } + void unlock() {} +}; + +mutex m; + +int main() +{ + std::unique_lock<mutex> lk(m, std::defer_lock); + assert(lk.try_lock() == true); + assert(try_lock_called == true); + assert(lk.owns_lock() == true); + try + { + lk.try_lock(); + assert(false); + } + catch (std::system_error& e) + { + assert(e.code().value() == EDEADLK); + } + lk.unlock(); + assert(lk.try_lock() == false); + assert(try_lock_called == false); + assert(lk.owns_lock() == false); + lk.release(); + try + { + lk.try_lock(); + assert(false); + } + catch (std::system_error& e) + { + assert(e.code().value() == EPERM); + } +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_for.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_for.pass.cpp new file mode 100644 index 000000000000..558f079463a4 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_for.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 + +// <mutex> + +// template <class Mutex> class unique_lock; + +// template <class Rep, class Period> +// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); + +#include <mutex> +#include <cassert> + +bool try_lock_for_called = false; + +typedef std::chrono::milliseconds ms; + +struct mutex +{ + template <class Rep, class Period> + bool try_lock_for(const std::chrono::duration<Rep, Period>& rel_time) + { + assert(rel_time == ms(5)); + try_lock_for_called = !try_lock_for_called; + return try_lock_for_called; + } + void unlock() {} +}; + +mutex m; + +int main() +{ + std::unique_lock<mutex> lk(m, std::defer_lock); + assert(lk.try_lock_for(ms(5)) == true); + assert(try_lock_for_called == true); + assert(lk.owns_lock() == true); + try + { + lk.try_lock_for(ms(5)); + assert(false); + } + catch (std::system_error& e) + { + assert(e.code().value() == EDEADLK); + } + lk.unlock(); + assert(lk.try_lock_for(ms(5)) == false); + assert(try_lock_for_called == false); + assert(lk.owns_lock() == false); + lk.release(); + try + { + lk.try_lock_for(ms(5)); + assert(false); + } + catch (std::system_error& e) + { + assert(e.code().value() == EPERM); + } +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_until.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_until.pass.cpp new file mode 100644 index 000000000000..24e4d109a097 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_until.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 + +// <mutex> + +// template <class Mutex> class unique_lock; + +// template <class Clock, class Duration> +// bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time); + +#include <mutex> +#include <cassert> + +bool try_lock_until_called = false; + +struct mutex +{ + template <class Clock, class Duration> + bool try_lock_until(const std::chrono::time_point<Clock, Duration>& abs_time) + { + typedef std::chrono::milliseconds ms; + assert(Clock::now() - abs_time < ms(5)); + try_lock_until_called = !try_lock_until_called; + return try_lock_until_called; + } + void unlock() {} +}; + +mutex m; + +int main() +{ + typedef std::chrono::steady_clock Clock; + std::unique_lock<mutex> lk(m, std::defer_lock); + assert(lk.try_lock_until(Clock::now()) == true); + assert(try_lock_until_called == true); + assert(lk.owns_lock() == true); + try + { + lk.try_lock_until(Clock::now()); + assert(false); + } + catch (std::system_error& e) + { + assert(e.code().value() == EDEADLK); + } + lk.unlock(); + assert(lk.try_lock_until(Clock::now()) == false); + assert(try_lock_until_called == false); + assert(lk.owns_lock() == false); + lk.release(); + try + { + lk.try_lock_until(Clock::now()); + assert(false); + } + catch (std::system_error& e) + { + assert(e.code().value() == EPERM); + } +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/unlock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/unlock.pass.cpp new file mode 100644 index 000000000000..bbabfc41df11 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/unlock.pass.cpp @@ -0,0 +1,56 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <mutex> + +// template <class Mutex> class unique_lock; + +// void unlock(); + +#include <mutex> +#include <cassert> + +bool unlock_called = false; + +struct mutex +{ + void lock() {} + void unlock() {unlock_called = true;} +}; + +mutex m; + +int main() +{ + std::unique_lock<mutex> lk(m); + lk.unlock(); + assert(unlock_called == true); + assert(lk.owns_lock() == false); + try + { + lk.unlock(); + assert(false); + } + catch (std::system_error& e) + { + assert(e.code().value() == EPERM); + } + lk.release(); + try + { + lk.unlock(); + assert(false); + } + catch (std::system_error& e) + { + assert(e.code().value() == EPERM); + } +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/member_swap.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/member_swap.pass.cpp new file mode 100644 index 000000000000..598d53a65c85 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/member_swap.pass.cpp @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <mutex> + +// template <class Mutex> class unique_lock; + +// void swap(unique_lock& u); + +#include <mutex> +#include <cassert> + +struct mutex +{ + void lock() {} + void unlock() {} +}; + +mutex m; + +int main() +{ + std::unique_lock<mutex> lk1(m); + std::unique_lock<mutex> lk2; + lk1.swap(lk2); + assert(lk1.mutex() == nullptr); + assert(lk1.owns_lock() == false); + assert(lk2.mutex() == &m); + assert(lk2.owns_lock() == true); +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/nonmember_swap.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/nonmember_swap.pass.cpp new file mode 100644 index 000000000000..3fc8c28f5071 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/nonmember_swap.pass.cpp @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <mutex> + +// template <class Mutex> class unique_lock; + +// template <class Mutex> +// void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y); + +#include <mutex> +#include <cassert> + +struct mutex +{ + void lock() {} + void unlock() {} +}; + +mutex m; + +int main() +{ + std::unique_lock<mutex> lk1(m); + std::unique_lock<mutex> lk2; + swap(lk1, lk2); + assert(lk1.mutex() == nullptr); + assert(lk1.owns_lock() == false); + assert(lk2.mutex() == &m); + assert(lk2.owns_lock() == true); +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/release.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/release.pass.cpp new file mode 100644 index 000000000000..89c28e6be73c --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/release.pass.cpp @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <mutex> + +// template <class Mutex> class unique_lock; + +// mutex_type* release() noexcept; + +#include <mutex> +#include <cassert> + +struct mutex +{ + static int lock_count; + static int unlock_count; + void lock() {++lock_count;} + void unlock() {++unlock_count;} +}; + +int mutex::lock_count = 0; +int mutex::unlock_count = 0; + +mutex m; + +int main() +{ + std::unique_lock<mutex> lk(m); + assert(lk.mutex() == &m); + assert(lk.owns_lock() == true); + assert(mutex::lock_count == 1); + assert(mutex::unlock_count == 0); + assert(lk.release() == &m); + assert(lk.mutex() == nullptr); + assert(lk.owns_lock() == false); + assert(mutex::lock_count == 1); + assert(mutex::unlock_count == 0); +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/mutex.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/mutex.pass.cpp new file mode 100644 index 000000000000..bc1e3e5eb774 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/mutex.pass.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <mutex> + +// template <class Mutex> class unique_lock; + +// mutex_type *mutex() const; + +#include <mutex> +#include <cassert> + +std::mutex m; + +int main() +{ + std::unique_lock<std::mutex> lk0; + assert(lk0.mutex() == nullptr); + std::unique_lock<std::mutex> lk1(m); + assert(lk1.mutex() == &m); + lk1.unlock(); + assert(lk1.mutex() == &m); +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/op_bool.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/op_bool.pass.cpp new file mode 100644 index 000000000000..7004ac0092e1 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/op_bool.pass.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <mutex> + +// template <class Mutex> class unique_lock; + +// explicit operator bool() const; + +#include <mutex> +#include <cassert> + +std::mutex m; + +int main() +{ + std::unique_lock<std::mutex> lk0; + assert(static_cast<bool>(lk0) == false); + std::unique_lock<std::mutex> lk1(m); + assert(static_cast<bool>(lk1) == true); + lk1.unlock(); + assert(static_cast<bool>(lk1) == false); +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/owns_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/owns_lock.pass.cpp new file mode 100644 index 000000000000..f53af35ff284 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/owns_lock.pass.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <mutex> + +// template <class Mutex> class unique_lock; + +// bool owns_lock() const; + +#include <mutex> +#include <cassert> + +std::mutex m; + +int main() +{ + std::unique_lock<std::mutex> lk0; + assert(lk0.owns_lock() == false); + std::unique_lock<std::mutex> lk1(m); + assert(lk1.owns_lock() == true); + lk1.unlock(); + assert(lk1.owns_lock() == false); +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/types.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/types.pass.cpp new file mode 100644 index 000000000000..f8bcb6d0d22f --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/types.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 + +// <mutex> + +// template <class Mutex> +// class unique_lock +// { +// public: +// typedef Mutex mutex_type; +// ... +// }; + +#include <mutex> +#include <type_traits> + +int main() +{ + static_assert((std::is_same<std::unique_lock<std::mutex>::mutex_type, + std::mutex>::value), ""); +} diff --git a/test/std/thread/thread.mutex/thread.lock/types.pass.cpp b/test/std/thread/thread.mutex/thread.lock/types.pass.cpp new file mode 100644 index 000000000000..64df0680b0b9 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/types.pass.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <mutex> + +// struct defer_lock_t {}; +// struct try_to_lock_t {}; +// struct adopt_lock_t {}; +// +// constexpr defer_lock_t defer_lock{}; +// constexpr try_to_lock_t try_to_lock{}; +// constexpr adopt_lock_t adopt_lock{}; + +#include <mutex> +#include <type_traits> + +int main() +{ + typedef std::defer_lock_t T1; + typedef std::try_to_lock_t T2; + typedef std::adopt_lock_t T3; + + T1 t1 = std::defer_lock; + T2 t2 = std::try_to_lock; + T3 t3 = std::adopt_lock; +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/nothing_to_do.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/nothing_to_do.pass.cpp new file mode 100644 index 000000000000..b58f5c55b643 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/nothing_to_do.pass.cpp @@ -0,0 +1,12 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +int main() +{ +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.general/nothing_to_do.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.general/nothing_to_do.pass.cpp new file mode 100644 index 000000000000..b58f5c55b643 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.general/nothing_to_do.pass.cpp @@ -0,0 +1,12 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +int main() +{ +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/nothing_to_do.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/nothing_to_do.pass.cpp new file mode 100644 index 000000000000..b58f5c55b643 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/nothing_to_do.pass.cpp @@ -0,0 +1,12 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +int main() +{ +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/assign.fail.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/assign.fail.cpp new file mode 100644 index 000000000000..7f6333af9e29 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/assign.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. +// +//===----------------------------------------------------------------------===// + +// <mutex> + +// class mutex; + +// mutex& operator=(const mutex&) = delete; + +#include <mutex> + +int main() +{ + std::mutex m0; + std::mutex m1; + m1 = m0; +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/copy.fail.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/copy.fail.cpp new file mode 100644 index 000000000000..7e1a07ac8c1a --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/copy.fail.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. +// +//===----------------------------------------------------------------------===// + +// <mutex> + +// class mutex; + +// mutex(const mutex&) = delete; + +#include <mutex> + +int main() +{ + std::mutex m0; + std::mutex m1(m0); +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/default.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/default.pass.cpp new file mode 100644 index 000000000000..4de42fbd0243 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/default.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 + +// <mutex> + +// class mutex; + +// mutex(); + +#include <mutex> + +int main() +{ + std::mutex m; +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/lock.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/lock.pass.cpp new file mode 100644 index 000000000000..ba2d54d58663 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/lock.pass.cpp @@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <mutex> + +// class mutex; + +// void lock(); + +#include <mutex> +#include <thread> +#include <cstdlib> +#include <cassert> + +#include <iostream> + +std::mutex m; + +typedef std::chrono::system_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef std::chrono::milliseconds ms; +typedef std::chrono::nanoseconds ns; + +void f() +{ + time_point t0 = Clock::now(); + m.lock(); + time_point t1 = Clock::now(); + m.unlock(); + ns d = t1 - t0 - ms(250); + assert(d < ms(50)); // within 50ms +} + +int main() +{ + m.lock(); + std::thread t(f); + std::this_thread::sleep_for(ms(250)); + m.unlock(); + t.join(); +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/native_handle.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/native_handle.pass.cpp new file mode 100644 index 000000000000..12c80f02c340 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/native_handle.pass.cpp @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <mutex> + +// class mutex; + +// typedef pthread_mutex_t* native_handle_type; +// native_handle_type native_handle(); + +#include <mutex> +#include <cassert> + +int main() +{ + std::mutex m; + pthread_mutex_t* h = m.native_handle(); + assert(h); +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/try_lock.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/try_lock.pass.cpp new file mode 100644 index 000000000000..fe8f351d7db7 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/try_lock.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 + +// <mutex> + +// class mutex; + +// bool try_lock(); + +#include <mutex> +#include <thread> +#include <cstdlib> +#include <cassert> + +std::mutex m; + +typedef std::chrono::system_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef std::chrono::milliseconds ms; +typedef std::chrono::nanoseconds ns; + +void f() +{ + time_point t0 = Clock::now(); + assert(!m.try_lock()); + assert(!m.try_lock()); + assert(!m.try_lock()); + while(!m.try_lock()) + ; + time_point t1 = Clock::now(); + m.unlock(); + ns d = t1 - t0 - ms(250); + assert(d < ms(200)); // within 200ms +} + +int main() +{ + m.lock(); + std::thread t(f); + std::this_thread::sleep_for(ms(250)); + m.unlock(); + t.join(); +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/assign.fail.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/assign.fail.cpp new file mode 100644 index 000000000000..61b56216e8fb --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/assign.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. +// +//===----------------------------------------------------------------------===// + +// <mutex> + +// class recursive_mutex; + +// recursive_mutex& operator=(const recursive_mutex&) = delete; + +#include <mutex> + +int main() +{ + std::recursive_mutex m0; + std::recursive_mutex m1; + m1 = m0; +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/copy.fail.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/copy.fail.cpp new file mode 100644 index 000000000000..0239c0475ac2 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/copy.fail.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. +// +//===----------------------------------------------------------------------===// + +// <mutex> + +// class recursive_mutex; + +// recursive_mutex(const recursive_mutex&) = delete; + +#include <mutex> + +int main() +{ + std::recursive_mutex m0; + std::recursive_mutex m1(m0); +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/default.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/default.pass.cpp new file mode 100644 index 000000000000..8c5d26675d3f --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/default.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 + +// <mutex> + +// class recursive_mutex; + +// recursive_mutex(); + +#include <mutex> + +int main() +{ + std::recursive_mutex m; +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/lock.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/lock.pass.cpp new file mode 100644 index 000000000000..abebe906378c --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/lock.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 + +// <mutex> + +// class recursive_mutex; + +// void lock(); + +#include <mutex> +#include <thread> +#include <cstdlib> +#include <cassert> + +#include <iostream> + +std::recursive_mutex m; + +typedef std::chrono::system_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef std::chrono::milliseconds ms; +typedef std::chrono::nanoseconds ns; + +void f() +{ + time_point t0 = Clock::now(); + m.lock(); + time_point t1 = Clock::now(); + m.lock(); + m.unlock(); + m.unlock(); + ns d = t1 - t0 - ms(250); + assert(d < ms(200)); // within 200ms +} + +int main() +{ + m.lock(); + std::thread t(f); + std::this_thread::sleep_for(ms(250)); + m.unlock(); + t.join(); +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/native_handle.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/native_handle.pass.cpp new file mode 100644 index 000000000000..10626bc4072e --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/native_handle.pass.cpp @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <mutex> + +// class recursive_mutex; + +// typedef pthread_mutex_t* native_handle_type; +// native_handle_type native_handle(); + +#include <mutex> +#include <cassert> + +int main() +{ + std::recursive_mutex m; + pthread_mutex_t* h = m.native_handle(); + assert(h); +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/try_lock.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/try_lock.pass.cpp new file mode 100644 index 000000000000..ff546d4ad66d --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/try_lock.pass.cpp @@ -0,0 +1,54 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <mutex> + +// class recursive_mutex; + +// bool try_lock(); + +#include <mutex> +#include <thread> +#include <cstdlib> +#include <cassert> + +std::recursive_mutex m; + +typedef std::chrono::system_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef std::chrono::milliseconds ms; +typedef std::chrono::nanoseconds ns; + +void f() +{ + time_point t0 = Clock::now(); + assert(!m.try_lock()); + assert(!m.try_lock()); + assert(!m.try_lock()); + while(!m.try_lock()) + ; + time_point t1 = Clock::now(); + assert(m.try_lock()); + m.unlock(); + m.unlock(); + ns d = t1 - t0 - ms(250); + assert(d < ms(200)); // within 200ms +} + +int main() +{ + m.lock(); + std::thread t(f); + std::this_thread::sleep_for(ms(250)); + m.unlock(); + t.join(); +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/nothing_to_do.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/nothing_to_do.pass.cpp new file mode 100644 index 000000000000..b58f5c55b643 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/nothing_to_do.pass.cpp @@ -0,0 +1,12 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +int main() +{ +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/assign.fail.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/assign.fail.cpp new file mode 100644 index 000000000000..7bcb2d61379a --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/assign.fail.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. +// +//===----------------------------------------------------------------------===// + +// <shared_mutex> + +// class shared_mutex; + +// shared_mutex& operator=(const shared_mutex&) = delete; + +#include <shared_mutex> + +#include "test_macros.h" + +int main() +{ +#if TEST_STD_VER > 14 + std::shared_mutex m0; + std::shared_mutex m1; + m1 = m0; +#else +# error +#endif +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/copy.fail.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/copy.fail.cpp new file mode 100644 index 000000000000..af064aeee26c --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/copy.fail.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// <shared_mutex> + +// class shared_mutex; + +// shared_mutex(const shared_mutex&) = delete; + +#include <shared_mutex> + +#include "test_macros.h" + +int main() +{ +#if TEST_STD_VER > 14 + std::shared_mutex m0; + std::shared_mutex m1(m0); +#else +# error +#endif +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/default.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/default.pass.cpp new file mode 100644 index 000000000000..c61a93aa0c7f --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/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 +// UNSUPPORTED: c++03, c++98, c++11, c++14 + +// <shared_mutex> + +// class shared_mutex; + +// shared_mutex(); + +#include <shared_mutex> + +int main() +{ + std::shared_mutex m; +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/lock.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/lock.pass.cpp new file mode 100644 index 000000000000..9bf7a79e3400 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/lock.pass.cpp @@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: c++03, c++98, c++11, c++14 + +// <shared_mutex> + +// class shared_mutex; + +// void lock(); + +#include <shared_mutex> +#include <thread> +#include <cstdlib> +#include <cassert> + + +std::shared_mutex m; + +typedef std::chrono::system_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef std::chrono::milliseconds ms; +typedef std::chrono::nanoseconds ns; + +void f() +{ + time_point t0 = Clock::now(); + m.lock(); + time_point t1 = Clock::now(); + m.unlock(); + ns d = t1 - t0 - ms(250); + assert(d < ms(50)); // within 50ms +} + +int main() +{ + m.lock(); + std::thread t(f); + std::this_thread::sleep_for(ms(250)); + m.unlock(); + t.join(); +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/lock_shared.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/lock_shared.pass.cpp new file mode 100644 index 000000000000..3ffa9e2d0065 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/lock_shared.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 +// UNSUPPORTED: c++03, c++98, c++11, c++14 + +// <shared_mutex> + +// class shared_mutex; + +// void lock_shared(); + +#include <shared_mutex> +#include <thread> +#include <vector> +#include <cstdlib> +#include <cassert> + +std::shared_mutex m; + +typedef std::chrono::system_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef std::chrono::milliseconds ms; +typedef std::chrono::nanoseconds ns; + +void f() +{ + time_point t0 = Clock::now(); + m.lock_shared(); + time_point t1 = Clock::now(); + m.unlock_shared(); + ns d = t1 - t0 - ms(250); + assert(d < ms(50)); // within 50ms +} + +void g() +{ + time_point t0 = Clock::now(); + m.lock_shared(); + time_point t1 = Clock::now(); + m.unlock_shared(); + ns d = t1 - t0; + assert(d < ms(50)); // within 50ms +} + + +int main() +{ + m.lock(); + std::vector<std::thread> v; + for (int i = 0; i < 5; ++i) + v.push_back(std::thread(f)); + std::this_thread::sleep_for(ms(250)); + m.unlock(); + for (auto& t : v) + t.join(); + m.lock_shared(); + for (auto& t : v) + t = std::thread(g); + std::thread q(f); + std::this_thread::sleep_for(ms(250)); + m.unlock_shared(); + for (auto& t : v) + t.join(); + q.join(); +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/try_lock.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/try_lock.pass.cpp new file mode 100644 index 000000000000..6f3ca24a4558 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/try_lock.pass.cpp @@ -0,0 +1,53 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: c++03, c++98, c++11, c++14 + +// <shared_mutex> + +// class shared_mutex; + +// bool try_lock(); + +#include <shared_mutex> +#include <thread> +#include <cstdlib> +#include <cassert> + +std::shared_mutex m; + +typedef std::chrono::system_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef std::chrono::milliseconds ms; +typedef std::chrono::nanoseconds ns; + +void f() +{ + time_point t0 = Clock::now(); + assert(!m.try_lock()); + assert(!m.try_lock()); + assert(!m.try_lock()); + while(!m.try_lock()) + ; + time_point t1 = Clock::now(); + m.unlock(); + ns d = t1 - t0 - ms(250); + assert(d < ms(200)); // within 200ms +} + +int main() +{ + m.lock(); + std::thread t(f); + std::this_thread::sleep_for(ms(250)); + m.unlock(); + t.join(); +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/try_lock_shared.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/try_lock_shared.pass.cpp new file mode 100644 index 000000000000..52007155ba5f --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/try_lock_shared.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 +// UNSUPPORTED: c++03, c++98, c++11, c++14 + +// <shared_mutex> + +// class shared_mutex; + +// bool try_lock_shared(); + +#include <shared_mutex> +#include <thread> +#include <vector> +#include <cstdlib> +#include <cassert> + +std::shared_mutex m; + +typedef std::chrono::system_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef std::chrono::milliseconds ms; +typedef std::chrono::nanoseconds ns; + +void f() +{ + time_point t0 = Clock::now(); + assert(!m.try_lock_shared()); + assert(!m.try_lock_shared()); + assert(!m.try_lock_shared()); + while(!m.try_lock_shared()) + ; + time_point t1 = Clock::now(); + m.unlock_shared(); + ns d = t1 - t0 - ms(250); + assert(d < ms(200)); // within 200ms +} + + +int main() +{ + m.lock(); + std::vector<std::thread> v; + for (int i = 0; i < 5; ++i) + v.push_back(std::thread(f)); + std::this_thread::sleep_for(ms(250)); + m.unlock(); + for (auto& t : v) + t.join(); +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/nothing_to_do.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/nothing_to_do.pass.cpp new file mode 100644 index 000000000000..b58f5c55b643 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/nothing_to_do.pass.cpp @@ -0,0 +1,12 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +int main() +{ +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/assign.fail.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/assign.fail.cpp new file mode 100644 index 000000000000..528aaca6d9e1 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/assign.fail.cpp @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// <shared_mutex> + +// class shared_timed_mutex; + +// shared_timed_mutex& operator=(const shared_timed_mutex&) = delete; + +#include <shared_mutex> + +int main() +{ +#if _LIBCPP_STD_VER > 11 + std::shared_timed_mutex m0; + std::shared_timed_mutex m1; + m1 = m0; +#else +# error +#endif +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/copy.fail.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/copy.fail.cpp new file mode 100644 index 000000000000..dbf01002e691 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/copy.fail.cpp @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// <shared_mutex> + +// class shared_timed_mutex; + +// shared_timed_mutex(const shared_timed_mutex&) = delete; + +#include <shared_mutex> + +int main() +{ +#if _LIBCPP_STD_VER > 11 + std::shared_timed_mutex m0; + std::shared_timed_mutex m1(m0); +#else +# error +#endif +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/default.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/default.pass.cpp new file mode 100644 index 000000000000..45cd563f9407 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/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 +// UNSUPPORTED: c++03, c++98, c++11 + +// <shared_mutex> + +// class shared_timed_mutex; + +// shared_timed_mutex(); + +#include <shared_mutex> + +int main() +{ + std::shared_timed_mutex m; +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/lock.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/lock.pass.cpp new file mode 100644 index 000000000000..62bb736837ea --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/lock.pass.cpp @@ -0,0 +1,49 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: c++03, c++98, c++11 + +// <shared_mutex> + +// class shared_timed_mutex; + +// void lock(); + +#include <shared_mutex> +#include <thread> +#include <cstdlib> +#include <cassert> + +std::shared_timed_mutex m; + +typedef std::chrono::system_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef std::chrono::milliseconds ms; +typedef std::chrono::nanoseconds ns; + +void f() +{ + time_point t0 = Clock::now(); + m.lock(); + time_point t1 = Clock::now(); + m.unlock(); + ns d = t1 - t0 - ms(250); + assert(d < ms(50)); // within 50ms +} + +int main() +{ + m.lock(); + std::thread t(f); + std::this_thread::sleep_for(ms(250)); + m.unlock(); + t.join(); +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/lock_shared.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/lock_shared.pass.cpp new file mode 100644 index 000000000000..8fc6299f1b8f --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/lock_shared.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 +// UNSUPPORTED: c++03, c++98, c++11 + +// <shared_mutex> + +// class shared_timed_mutex; + +// void lock_shared(); + +#include <shared_mutex> +#include <thread> +#include <vector> +#include <cstdlib> +#include <cassert> + +std::shared_timed_mutex m; + +typedef std::chrono::system_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef std::chrono::milliseconds ms; +typedef std::chrono::nanoseconds ns; + +void f() +{ + time_point t0 = Clock::now(); + m.lock_shared(); + time_point t1 = Clock::now(); + m.unlock_shared(); + ns d = t1 - t0 - ms(250); + assert(d < ms(50)); // within 50ms +} + +void g() +{ + time_point t0 = Clock::now(); + m.lock_shared(); + time_point t1 = Clock::now(); + m.unlock_shared(); + ns d = t1 - t0; + assert(d < ms(50)); // within 50ms +} + + +int main() +{ + m.lock(); + std::vector<std::thread> v; + for (int i = 0; i < 5; ++i) + v.push_back(std::thread(f)); + std::this_thread::sleep_for(ms(250)); + m.unlock(); + for (auto& t : v) + t.join(); + m.lock_shared(); + for (auto& t : v) + t = std::thread(g); + std::thread q(f); + std::this_thread::sleep_for(ms(250)); + m.unlock_shared(); + for (auto& t : v) + t.join(); + q.join(); +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock.pass.cpp new file mode 100644 index 000000000000..61900ba83342 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock.pass.cpp @@ -0,0 +1,53 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: c++03, c++98, c++11 + +// <shared_mutex> + +// class shared_timed_mutex; + +// bool try_lock(); + +#include <shared_mutex> +#include <thread> +#include <cstdlib> +#include <cassert> + +std::shared_timed_mutex m; + +typedef std::chrono::system_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef std::chrono::milliseconds ms; +typedef std::chrono::nanoseconds ns; + +void f() +{ + time_point t0 = Clock::now(); + assert(!m.try_lock()); + assert(!m.try_lock()); + assert(!m.try_lock()); + while(!m.try_lock()) + ; + time_point t1 = Clock::now(); + m.unlock(); + ns d = t1 - t0 - ms(250); + assert(d < ms(200)); // within 200ms +} + +int main() +{ + m.lock(); + std::thread t(f); + std::this_thread::sleep_for(ms(250)); + m.unlock(); + t.join(); +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_for.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_for.pass.cpp new file mode 100644 index 000000000000..ab20241895ba --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_for.pass.cpp @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: c++03, c++98, c++11 + +// <shared_mutex> + +// class shared_timed_mutex; + +// template <class Rep, class Period> +// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); + +#include <shared_mutex> +#include <thread> +#include <cstdlib> +#include <cassert> + +std::shared_timed_mutex m; + +typedef std::chrono::steady_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef std::chrono::milliseconds ms; +typedef std::chrono::nanoseconds ns; + +void f1() +{ + time_point t0 = Clock::now(); + assert(m.try_lock_for(ms(300)) == true); + time_point t1 = Clock::now(); + m.unlock(); + ns d = t1 - t0 - ms(250); + assert(d < ms(50)); // within 50ms +} + +void f2() +{ + time_point t0 = Clock::now(); + assert(m.try_lock_for(ms(250)) == false); + time_point t1 = Clock::now(); + ns d = t1 - t0 - ms(250); + assert(d < ms(50)); // within 50ms +} + +int main() +{ + { + m.lock(); + std::thread t(f1); + std::this_thread::sleep_for(ms(250)); + m.unlock(); + t.join(); + } + { + m.lock(); + std::thread t(f2); + std::this_thread::sleep_for(ms(300)); + m.unlock(); + t.join(); + } +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared.pass.cpp new file mode 100644 index 000000000000..9c2d8c9c8e5c --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared.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 +// UNSUPPORTED: c++03, c++98, c++11 + +// <shared_mutex> + +// class shared_timed_mutex; + +// bool try_lock_shared(); + +#include <shared_mutex> +#include <thread> +#include <vector> +#include <cstdlib> +#include <cassert> + +std::shared_timed_mutex m; + +typedef std::chrono::system_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef std::chrono::milliseconds ms; +typedef std::chrono::nanoseconds ns; + +void f() +{ + time_point t0 = Clock::now(); + assert(!m.try_lock_shared()); + assert(!m.try_lock_shared()); + assert(!m.try_lock_shared()); + while(!m.try_lock_shared()) + ; + time_point t1 = Clock::now(); + m.unlock_shared(); + ns d = t1 - t0 - ms(250); + assert(d < ms(200)); // within 200ms +} + +int main() +{ + m.lock(); + std::vector<std::thread> v; + for (int i = 0; i < 5; ++i) + v.push_back(std::thread(f)); + std::this_thread::sleep_for(ms(250)); + m.unlock(); + for (auto& t : v) + t.join(); +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared_for.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared_for.pass.cpp new file mode 100644 index 000000000000..35444112a5da --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared_for.pass.cpp @@ -0,0 +1,75 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: c++03, c++98, c++11 + +// <shared_mutex> + +// class shared_timed_mutex; + +// template <class Rep, class Period> +// bool try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time); + +#include <shared_mutex> +#include <thread> +#include <vector> +#include <cstdlib> +#include <cassert> + +std::shared_timed_mutex m; + +typedef std::chrono::steady_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef std::chrono::milliseconds ms; +typedef std::chrono::nanoseconds ns; + +void f1() +{ + time_point t0 = Clock::now(); + assert(m.try_lock_shared_for(ms(300)) == true); + time_point t1 = Clock::now(); + m.unlock_shared(); + ns d = t1 - t0 - ms(250); + assert(d < ms(50)); // within 50ms +} + +void f2() +{ + time_point t0 = Clock::now(); + assert(m.try_lock_shared_for(ms(250)) == false); + time_point t1 = Clock::now(); + ns d = t1 - t0 - ms(250); + assert(d < ms(50)); // within 50ms +} + +int main() +{ + { + m.lock(); + std::vector<std::thread> v; + for (int i = 0; i < 5; ++i) + v.push_back(std::thread(f1)); + std::this_thread::sleep_for(ms(250)); + m.unlock(); + for (auto& t : v) + t.join(); + } + { + m.lock(); + std::vector<std::thread> v; + for (int i = 0; i < 5; ++i) + v.push_back(std::thread(f2)); + std::this_thread::sleep_for(ms(300)); + m.unlock(); + for (auto& t : v) + t.join(); + } +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared_until.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared_until.pass.cpp new file mode 100644 index 000000000000..4e0f19de07ce --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared_until.pass.cpp @@ -0,0 +1,75 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: c++03, c++98, c++11 + +// <shared_mutex> + +// class shared_timed_mutex; + +// template <class Clock, class Duration> +// bool try_lock_shared_until(const chrono::time_point<Clock, Duration>& abs_time); + +#include <shared_mutex> +#include <thread> +#include <vector> +#include <cstdlib> +#include <cassert> + +std::shared_timed_mutex m; + +typedef std::chrono::steady_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef std::chrono::milliseconds ms; +typedef std::chrono::nanoseconds ns; + +void f1() +{ + time_point t0 = Clock::now(); + assert(m.try_lock_shared_until(Clock::now() + ms(300)) == true); + time_point t1 = Clock::now(); + m.unlock_shared(); + ns d = t1 - t0 - ms(250); + assert(d < ms(50)); // within 50ms +} + +void f2() +{ + time_point t0 = Clock::now(); + assert(m.try_lock_shared_until(Clock::now() + ms(250)) == false); + time_point t1 = Clock::now(); + ns d = t1 - t0 - ms(250); + assert(d < ms(50)); // within 50ms +} + +int main() +{ + { + m.lock(); + std::vector<std::thread> v; + for (int i = 0; i < 5; ++i) + v.push_back(std::thread(f1)); + std::this_thread::sleep_for(ms(250)); + m.unlock(); + for (auto& t : v) + t.join(); + } + { + m.lock(); + std::vector<std::thread> v; + for (int i = 0; i < 5; ++i) + v.push_back(std::thread(f2)); + std::this_thread::sleep_for(ms(300)); + m.unlock(); + for (auto& t : v) + t.join(); + } +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_until.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_until.pass.cpp new file mode 100644 index 000000000000..aa90cf71502f --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_until.pass.cpp @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: c++03, c++98, c++11 + +// <shared_mutex> + +// class shared_timed_mutex; + +// template <class Clock, class Duration> +// bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time); + +#include <shared_mutex> +#include <thread> +#include <cstdlib> +#include <cassert> + +#include "test_macros.h" + +std::shared_timed_mutex m; + +typedef std::chrono::steady_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef std::chrono::milliseconds ms; +typedef std::chrono::nanoseconds ns; + +void f1() +{ + time_point t0 = Clock::now(); + assert(m.try_lock_until(Clock::now() + ms(300)) == true); + time_point t1 = Clock::now(); + m.unlock(); + ns d = t1 - t0 - ms(250); + assert(d < ms(50)); // within 50ms +} + +void f2() +{ + time_point t0 = Clock::now(); + assert(m.try_lock_until(Clock::now() + ms(250)) == false); + time_point t1 = Clock::now(); + ns d = t1 - t0 - ms(250); + assert(d < ms(50)); // within 50ms +} + +int main() +{ + { + m.lock(); + std::thread t(f1); + std::this_thread::sleep_for(ms(250)); + m.unlock(); + t.join(); + } + { + m.lock(); + std::thread t(f2); + std::this_thread::sleep_for(ms(300)); + m.unlock(); + t.join(); + } +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_until_deadlock_bug.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_until_deadlock_bug.pass.cpp new file mode 100644 index 000000000000..ed288099c979 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_until_deadlock_bug.pass.cpp @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: c++03, c++98, c++11 + +// <shared_mutex> + +// class shared_timed_mutex; + +#include <shared_mutex> + +#include <atomic> +#include <chrono> +#include <thread> +#include <cstdlib> +#include <cassert> + +std::shared_timed_mutex m; + +const int total_readers = 2; +std::atomic<int> readers_started(0); +std::atomic<int> readers_finished(0); + +// Wait for the readers to start then try and acquire the write lock. +void writer_one() { + while (readers_started != total_readers) {} + bool b = m.try_lock_for(std::chrono::milliseconds(500)); + assert(b == false); +} + +void blocked_reader() { + ++readers_started; + // Wait until writer_one is waiting for the write lock. + while (m.try_lock_shared()) { + m.unlock_shared(); + } + // Attempt to get the read lock. writer_one should be blocking us because + // writer_one is blocked by main. + m.lock_shared(); + ++readers_finished; + m.unlock_shared(); +} + +int main() +{ + typedef std::chrono::steady_clock Clock; + + m.lock_shared(); + std::thread t1(writer_one); + // create some readers + std::thread t2(blocked_reader); + std::thread t3(blocked_reader); + // Kill the test after 10 seconds if it hasn't completed. + auto end_point = Clock::now() + std::chrono::seconds(10); + while (readers_finished != total_readers && Clock::now() < end_point) { + std::this_thread::sleep_for(std::chrono::seconds(1)); + } + assert(readers_finished == total_readers); + m.unlock_shared(); + t1.join(); + t2.join(); + t3.join(); +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/nothing_to_do.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/nothing_to_do.pass.cpp new file mode 100644 index 000000000000..b58f5c55b643 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/nothing_to_do.pass.cpp @@ -0,0 +1,12 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +int main() +{ +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/assign.fail.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/assign.fail.cpp new file mode 100644 index 000000000000..58006833ecac --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/assign.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. +// +//===----------------------------------------------------------------------===// + +// <mutex> + +// class timed_mutex; + +// timed_mutex& operator=(const timed_mutex&) = delete; + +#include <mutex> + +int main() +{ + std::timed_mutex m0; + std::timed_mutex m1; + m1 = m0; +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/copy.fail.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/copy.fail.cpp new file mode 100644 index 000000000000..61ba31d8648e --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/copy.fail.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. +// +//===----------------------------------------------------------------------===// + +// <mutex> + +// class timed_mutex; + +// timed_mutex(const timed_mutex&) = delete; + +#include <mutex> + +int main() +{ + std::timed_mutex m0; + std::timed_mutex m1(m0); +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/default.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/default.pass.cpp new file mode 100644 index 000000000000..33320a7e260a --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/default.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 + +// <mutex> + +// class timed_mutex; + +// timed_mutex(); + +#include <mutex> + +int main() +{ + std::timed_mutex m; +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/lock.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/lock.pass.cpp new file mode 100644 index 000000000000..fe2dd825c207 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/lock.pass.cpp @@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <mutex> + +// class timed_mutex; + +// void lock(); + +#include <mutex> +#include <thread> +#include <cstdlib> +#include <cassert> + +#include <iostream> + +std::timed_mutex m; + +typedef std::chrono::system_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef std::chrono::milliseconds ms; +typedef std::chrono::nanoseconds ns; + +void f() +{ + time_point t0 = Clock::now(); + m.lock(); + time_point t1 = Clock::now(); + m.unlock(); + ns d = t1 - t0 - ms(250); + assert(d < ms(50)); // within 50ms +} + +int main() +{ + m.lock(); + std::thread t(f); + std::this_thread::sleep_for(ms(250)); + m.unlock(); + t.join(); +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/try_lock.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/try_lock.pass.cpp new file mode 100644 index 000000000000..b32a2664551a --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/try_lock.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 + +// <mutex> + +// class timed_mutex; + +// bool try_lock(); + +#include <mutex> +#include <thread> +#include <cstdlib> +#include <cassert> + +std::timed_mutex m; + +typedef std::chrono::system_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef std::chrono::milliseconds ms; +typedef std::chrono::nanoseconds ns; + +void f() +{ + time_point t0 = Clock::now(); + assert(!m.try_lock()); + assert(!m.try_lock()); + assert(!m.try_lock()); + while(!m.try_lock()) + ; + time_point t1 = Clock::now(); + m.unlock(); + ns d = t1 - t0 - ms(250); + assert(d < ms(200)); // within 200ms +} + +int main() +{ + m.lock(); + std::thread t(f); + std::this_thread::sleep_for(ms(250)); + m.unlock(); + t.join(); +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/try_lock_for.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/try_lock_for.pass.cpp new file mode 100644 index 000000000000..46222a70c8d9 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/try_lock_for.pass.cpp @@ -0,0 +1,67 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <mutex> + +// class timed_mutex; + +// template <class Rep, class Period> +// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); + +#include <mutex> +#include <thread> +#include <cstdlib> +#include <cassert> + +std::timed_mutex m; + +typedef std::chrono::steady_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef std::chrono::milliseconds ms; +typedef std::chrono::nanoseconds ns; + +void f1() +{ + time_point t0 = Clock::now(); + assert(m.try_lock_for(ms(300)) == true); + time_point t1 = Clock::now(); + m.unlock(); + ns d = t1 - t0 - ms(250); + assert(d < ms(50)); // within 50ms +} + +void f2() +{ + time_point t0 = Clock::now(); + assert(m.try_lock_for(ms(250)) == false); + time_point t1 = Clock::now(); + ns d = t1 - t0 - ms(250); + assert(d < ms(50)); // within 50ms +} + +int main() +{ + { + m.lock(); + std::thread t(f1); + std::this_thread::sleep_for(ms(250)); + m.unlock(); + t.join(); + } + { + m.lock(); + std::thread t(f2); + std::this_thread::sleep_for(ms(300)); + m.unlock(); + t.join(); + } +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/try_lock_until.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/try_lock_until.pass.cpp new file mode 100644 index 000000000000..6c9c442ab124 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/try_lock_until.pass.cpp @@ -0,0 +1,67 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <mutex> + +// class timed_mutex; + +// template <class Clock, class Duration> +// bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time); + +#include <mutex> +#include <thread> +#include <cstdlib> +#include <cassert> + +std::timed_mutex m; + +typedef std::chrono::steady_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef std::chrono::milliseconds ms; +typedef std::chrono::nanoseconds ns; + +void f1() +{ + time_point t0 = Clock::now(); + assert(m.try_lock_until(Clock::now() + ms(300)) == true); + time_point t1 = Clock::now(); + m.unlock(); + ns d = t1 - t0 - ms(250); + assert(d < ms(50)); // within 50ms +} + +void f2() +{ + time_point t0 = Clock::now(); + assert(m.try_lock_until(Clock::now() + ms(250)) == false); + time_point t1 = Clock::now(); + ns d = t1 - t0 - ms(250); + assert(d < ms(50)); // within 50ms +} + +int main() +{ + { + m.lock(); + std::thread t(f1); + std::this_thread::sleep_for(ms(250)); + m.unlock(); + t.join(); + } + { + m.lock(); + std::thread t(f2); + std::this_thread::sleep_for(ms(300)); + m.unlock(); + t.join(); + } +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/assign.fail.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/assign.fail.cpp new file mode 100644 index 000000000000..ae84be838d66 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/assign.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. +// +//===----------------------------------------------------------------------===// + +// <mutex> + +// class recursive_timed_mutex; + +// recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete; + +#include <mutex> + +int main() +{ + std::recursive_timed_mutex m0; + std::recursive_timed_mutex m1; + m1 = m0; +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/copy.fail.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/copy.fail.cpp new file mode 100644 index 000000000000..487d6a8c269c --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/copy.fail.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. +// +//===----------------------------------------------------------------------===// + +// <mutex> + +// class recursive_timed_mutex; + +// recursive_timed_mutex(const recursive_timed_mutex&) = delete; + +#include <mutex> + +int main() +{ + std::recursive_timed_mutex m0; + std::recursive_timed_mutex m1(m0); +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/default.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/default.pass.cpp new file mode 100644 index 000000000000..56e1874dc126 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/default.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 + +// <mutex> + +// class recursive_timed_mutex; + +// recursive_timed_mutex(); + +#include <mutex> + +int main() +{ + std::recursive_timed_mutex m; +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/lock.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/lock.pass.cpp new file mode 100644 index 000000000000..91f747bc1ab0 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/lock.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 + +// <mutex> + +// class recursive_timed_mutex; + +// void lock(); + +#include <mutex> +#include <thread> +#include <cstdlib> +#include <cassert> + +#include <iostream> + +std::recursive_timed_mutex m; + +typedef std::chrono::system_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef std::chrono::milliseconds ms; +typedef std::chrono::nanoseconds ns; + +void f() +{ + time_point t0 = Clock::now(); + m.lock(); + time_point t1 = Clock::now(); + m.lock(); + m.unlock(); + m.unlock(); + ns d = t1 - t0 - ms(250); + assert(d < ms(50)); // within 50ms +} + +int main() +{ + m.lock(); + std::thread t(f); + std::this_thread::sleep_for(ms(250)); + m.unlock(); + t.join(); +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/try_lock.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/try_lock.pass.cpp new file mode 100644 index 000000000000..63c3cfee38a3 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/try_lock.pass.cpp @@ -0,0 +1,54 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <mutex> + +// class recursive_timed_mutex; + +// bool try_lock(); + +#include <mutex> +#include <thread> +#include <cstdlib> +#include <cassert> + +std::recursive_timed_mutex m; + +typedef std::chrono::system_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef std::chrono::milliseconds ms; +typedef std::chrono::nanoseconds ns; + +void f() +{ + time_point t0 = Clock::now(); + assert(!m.try_lock()); + assert(!m.try_lock()); + assert(!m.try_lock()); + while(!m.try_lock()) + ; + time_point t1 = Clock::now(); + assert(m.try_lock()); + m.unlock(); + m.unlock(); + ns d = t1 - t0 - ms(250); + assert(d < ms(200)); // within 200ms +} + +int main() +{ + m.lock(); + std::thread t(f); + std::this_thread::sleep_for(ms(250)); + m.unlock(); + t.join(); +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/try_lock_for.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/try_lock_for.pass.cpp new file mode 100644 index 000000000000..3c1d6ddc6f40 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/try_lock_for.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 + +// <mutex> + +// class recursive_timed_mutex; + +// template <class Rep, class Period> +// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); + +#include <mutex> +#include <thread> +#include <cstdlib> +#include <cassert> + +std::recursive_timed_mutex m; + +typedef std::chrono::steady_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef std::chrono::milliseconds ms; +typedef std::chrono::nanoseconds ns; + +void f1() +{ + time_point t0 = Clock::now(); + assert(m.try_lock_for(ms(300)) == true); + time_point t1 = Clock::now(); + assert(m.try_lock()); + m.unlock(); + m.unlock(); + ns d = t1 - t0 - ms(250); + assert(d < ns(50000000)); // within 50ms +} + +void f2() +{ + time_point t0 = Clock::now(); + assert(m.try_lock_for(ms(250)) == false); + time_point t1 = Clock::now(); + ns d = t1 - t0 - ms(250); + assert(d < ns(50000000)); // within 50ms +} + +int main() +{ + { + m.lock(); + std::thread t(f1); + std::this_thread::sleep_for(ms(250)); + m.unlock(); + t.join(); + } + { + m.lock(); + std::thread t(f2); + std::this_thread::sleep_for(ms(300)); + m.unlock(); + t.join(); + } +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/try_lock_until.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/try_lock_until.pass.cpp new file mode 100644 index 000000000000..066eb7b3064c --- /dev/null +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/try_lock_until.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 + +// <mutex> + +// class recursive_timed_mutex; + +// template <class Clock, class Duration> +// bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time); + +#include <mutex> +#include <thread> +#include <cstdlib> +#include <cassert> + +std::recursive_timed_mutex m; + +typedef std::chrono::steady_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef std::chrono::milliseconds ms; +typedef std::chrono::nanoseconds ns; + +void f1() +{ + time_point t0 = Clock::now(); + assert(m.try_lock_until(Clock::now() + ms(300)) == true); + time_point t1 = Clock::now(); + assert(m.try_lock()); + m.unlock(); + m.unlock(); + ns d = t1 - t0 - ms(250); + assert(d < ms(50)); // within 50ms +} + +void f2() +{ + time_point t0 = Clock::now(); + assert(m.try_lock_until(Clock::now() + ms(250)) == false); + time_point t1 = Clock::now(); + ns d = t1 - t0 - ms(250); + assert(d < ms(50)); // within 50ms +} + +int main() +{ + { + m.lock(); + std::thread t(f1); + std::this_thread::sleep_for(ms(250)); + m.unlock(); + t.join(); + } + { + m.lock(); + std::thread t(f2); + std::this_thread::sleep_for(ms(300)); + m.unlock(); + t.join(); + } +} diff --git a/test/std/thread/thread.mutex/thread.once/nothing_to_do.pass.cpp b/test/std/thread/thread.mutex/thread.once/nothing_to_do.pass.cpp new file mode 100644 index 000000000000..b58f5c55b643 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.once/nothing_to_do.pass.cpp @@ -0,0 +1,12 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +int main() +{ +} diff --git a/test/std/thread/thread.mutex/thread.once/thread.once.callonce/call_once.pass.cpp b/test/std/thread/thread.mutex/thread.once/thread.once.callonce/call_once.pass.cpp new file mode 100644 index 000000000000..89b99348459b --- /dev/null +++ b/test/std/thread/thread.mutex/thread.once/thread.once.callonce/call_once.pass.cpp @@ -0,0 +1,254 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <mutex> + +// struct once_flag; + +// template<class Callable, class ...Args> +// void call_once(once_flag& flag, Callable&& func, Args&&... args); + +#include <mutex> +#include <thread> +#include <cassert> + +typedef std::chrono::milliseconds ms; + +std::once_flag flg0; + +int init0_called = 0; + +void init0() +{ + std::this_thread::sleep_for(ms(250)); + ++init0_called; +} + +void f0() +{ + std::call_once(flg0, init0); +} + +std::once_flag flg3; + +int init3_called = 0; +int init3_completed = 0; + +void init3() +{ + ++init3_called; + std::this_thread::sleep_for(ms(250)); + if (init3_called == 1) + throw 1; + ++init3_completed; +} + +void f3() +{ + try + { + std::call_once(flg3, init3); + } + catch (...) + { + } +} + +#ifndef _LIBCPP_HAS_NO_VARIADICS + +struct init1 +{ + static int called; + + void operator()(int i) {called += i;} +}; + +int init1::called = 0; + +std::once_flag flg1; + +void f1() +{ + std::call_once(flg1, init1(), 1); +} + +struct init2 +{ + static int called; + + void operator()(int i, int j) const {called += i + j;} +}; + +int init2::called = 0; + +std::once_flag flg2; + +void f2() +{ + std::call_once(flg2, init2(), 2, 3); + std::call_once(flg2, init2(), 4, 5); +} + +#endif // _LIBCPP_HAS_NO_VARIADICS + +std::once_flag flg41; +std::once_flag flg42; + +int init41_called = 0; +int init42_called = 0; + +void init42(); + +void init41() +{ + std::this_thread::sleep_for(ms(250)); + ++init41_called; +} + +void init42() +{ + std::this_thread::sleep_for(ms(250)); + ++init42_called; +} + +void f41() +{ + std::call_once(flg41, init41); + std::call_once(flg42, init42); +} + +void f42() +{ + std::call_once(flg42, init42); + std::call_once(flg41, init41); +} + +#ifndef _LIBCPP_HAS_NO_VARIADICS + +class MoveOnly +{ +#if !defined(__clang__) + // GCC 4.8 complains about the following being private +public: + MoveOnly(const MoveOnly&) + { + } +#else + MoveOnly(const MoveOnly&); +#endif +public: + MoveOnly() {} + MoveOnly(MoveOnly&&) {} + + void operator()(MoveOnly&&) + { + } +}; + +class NonCopyable +{ +#if !defined(__clang__) + // GCC 4.8 complains about the following being private +public: + NonCopyable(const NonCopyable&) + { + } +#else + NonCopyable(const NonCopyable&); +#endif +public: + NonCopyable() {} + + void operator()(int&) {} +}; + +#if __cplusplus >= 201103L +// reference qualifiers on functions are a C++11 extension +struct RefQual +{ + int lv_called, rv_called; + + RefQual() : lv_called(0), rv_called(0) {} + + void operator()() & { ++lv_called; } + void operator()() && { ++rv_called; } +}; +#endif +#endif + +int main() +{ + // check basic functionality + { + std::thread t0(f0); + std::thread t1(f0); + t0.join(); + t1.join(); + assert(init0_called == 1); + } + // check basic exception safety + { + std::thread t0(f3); + std::thread t1(f3); + t0.join(); + t1.join(); + assert(init3_called == 2); + assert(init3_completed == 1); + } + // check deadlock avoidance + { + std::thread t0(f41); + std::thread t1(f42); + t0.join(); + t1.join(); + assert(init41_called == 1); + assert(init42_called == 1); + } +#ifndef _LIBCPP_HAS_NO_VARIADICS + // check functors with 1 arg + { + std::thread t0(f1); + std::thread t1(f1); + t0.join(); + t1.join(); + assert(init1::called == 1); + } + // check functors with 2 args + { + std::thread t0(f2); + std::thread t1(f2); + t0.join(); + t1.join(); + assert(init2::called == 5); + } + { + std::once_flag f; + std::call_once(f, MoveOnly(), MoveOnly()); + } + // check LWG2442: call_once() shouldn't DECAY_COPY() + { + std::once_flag f; + int i = 0; + std::call_once(f, NonCopyable(), i); + } +#if __cplusplus >= 201103L +// reference qualifiers on functions are a C++11 extension + { + std::once_flag f1, f2; + RefQual rq; + std::call_once(f1, rq); + assert(rq.lv_called == 1); + std::call_once(f2, std::move(rq)); + assert(rq.rv_called == 1); + } +#endif +#endif // _LIBCPP_HAS_NO_VARIADICS +} diff --git a/test/std/thread/thread.mutex/thread.once/thread.once.onceflag/assign.fail.cpp b/test/std/thread/thread.mutex/thread.once/thread.once.onceflag/assign.fail.cpp new file mode 100644 index 000000000000..c4714276432c --- /dev/null +++ b/test/std/thread/thread.mutex/thread.once/thread.once.onceflag/assign.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. +// +//===----------------------------------------------------------------------===// + +// <mutex> + +// struct once_flag; + +// once_flag& operator=(const once_flag&) = delete; + +#include <mutex> + +int main() +{ + std::once_flag f; + std::once_flag f2; + f2 = f; +} diff --git a/test/std/thread/thread.mutex/thread.once/thread.once.onceflag/copy.fail.cpp b/test/std/thread/thread.mutex/thread.once/thread.once.onceflag/copy.fail.cpp new file mode 100644 index 000000000000..450ba8361391 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.once/thread.once.onceflag/copy.fail.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. +// +//===----------------------------------------------------------------------===// + +// <mutex> + +// struct once_flag; + +// once_flag(const once_flag&) = delete; + +#include <mutex> + +int main() +{ + std::once_flag f; + std::once_flag f2(f); +} diff --git a/test/std/thread/thread.mutex/thread.once/thread.once.onceflag/default.pass.cpp b/test/std/thread/thread.mutex/thread.once/thread.once.onceflag/default.pass.cpp new file mode 100644 index 000000000000..6995f0648335 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.once/thread.once.onceflag/default.pass.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// <mutex> + +// struct once_flag; + +// constexpr once_flag() noexcept; + +#include <mutex> + +int main() +{ + { + std::once_flag f; + } +#ifndef _LIBCPP_HAS_NO_CONSTEXPR + { + constexpr std::once_flag f; + } +#endif +} diff --git a/test/std/thread/thread.mutex/version.pass.cpp b/test/std/thread/thread.mutex/version.pass.cpp new file mode 100644 index 000000000000..81b52c79204b --- /dev/null +++ b/test/std/thread/thread.mutex/version.pass.cpp @@ -0,0 +1,20 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// <mutex> + +#include <mutex> + +#ifndef _LIBCPP_VERSION +#error _LIBCPP_VERSION not defined +#endif + +int main() +{ +} diff --git a/test/std/thread/thread.req/nothing_to_do.pass.cpp b/test/std/thread/thread.req/nothing_to_do.pass.cpp new file mode 100644 index 000000000000..b58f5c55b643 --- /dev/null +++ b/test/std/thread/thread.req/nothing_to_do.pass.cpp @@ -0,0 +1,12 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +int main() +{ +} diff --git a/test/std/thread/thread.req/thread.req.exception/nothing_to_do.pass.cpp b/test/std/thread/thread.req/thread.req.exception/nothing_to_do.pass.cpp new file mode 100644 index 000000000000..b58f5c55b643 --- /dev/null +++ b/test/std/thread/thread.req/thread.req.exception/nothing_to_do.pass.cpp @@ -0,0 +1,12 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +int main() +{ +} diff --git a/test/std/thread/thread.req/thread.req.lockable/nothing_to_do.pass.cpp b/test/std/thread/thread.req/thread.req.lockable/nothing_to_do.pass.cpp new file mode 100644 index 000000000000..b58f5c55b643 --- /dev/null +++ b/test/std/thread/thread.req/thread.req.lockable/nothing_to_do.pass.cpp @@ -0,0 +1,12 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +int main() +{ +} diff --git a/test/std/thread/thread.req/thread.req.lockable/thread.req.lockable.basic/nothing_to_do.pass.cpp b/test/std/thread/thread.req/thread.req.lockable/thread.req.lockable.basic/nothing_to_do.pass.cpp new file mode 100644 index 000000000000..b58f5c55b643 --- /dev/null +++ b/test/std/thread/thread.req/thread.req.lockable/thread.req.lockable.basic/nothing_to_do.pass.cpp @@ -0,0 +1,12 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +int main() +{ +} diff --git a/test/std/thread/thread.req/thread.req.lockable/thread.req.lockable.general/nothing_to_do.pass.cpp b/test/std/thread/thread.req/thread.req.lockable/thread.req.lockable.general/nothing_to_do.pass.cpp new file mode 100644 index 000000000000..b58f5c55b643 --- /dev/null +++ b/test/std/thread/thread.req/thread.req.lockable/thread.req.lockable.general/nothing_to_do.pass.cpp @@ -0,0 +1,12 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +int main() +{ +} diff --git a/test/std/thread/thread.req/thread.req.lockable/thread.req.lockable.req/nothing_to_do.pass.cpp b/test/std/thread/thread.req/thread.req.lockable/thread.req.lockable.req/nothing_to_do.pass.cpp new file mode 100644 index 000000000000..b58f5c55b643 --- /dev/null +++ b/test/std/thread/thread.req/thread.req.lockable/thread.req.lockable.req/nothing_to_do.pass.cpp @@ -0,0 +1,12 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +int main() +{ +} diff --git a/test/std/thread/thread.req/thread.req.lockable/thread.req.lockable.timed/nothing_to_do.pass.cpp b/test/std/thread/thread.req/thread.req.lockable/thread.req.lockable.timed/nothing_to_do.pass.cpp new file mode 100644 index 000000000000..b58f5c55b643 --- /dev/null +++ b/test/std/thread/thread.req/thread.req.lockable/thread.req.lockable.timed/nothing_to_do.pass.cpp @@ -0,0 +1,12 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +int main() +{ +} diff --git a/test/std/thread/thread.req/thread.req.native/nothing_to_do.pass.cpp b/test/std/thread/thread.req/thread.req.native/nothing_to_do.pass.cpp new file mode 100644 index 000000000000..b58f5c55b643 --- /dev/null +++ b/test/std/thread/thread.req/thread.req.native/nothing_to_do.pass.cpp @@ -0,0 +1,12 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +int main() +{ +} diff --git a/test/std/thread/thread.req/thread.req.paramname/nothing_to_do.pass.cpp b/test/std/thread/thread.req/thread.req.paramname/nothing_to_do.pass.cpp new file mode 100644 index 000000000000..b58f5c55b643 --- /dev/null +++ b/test/std/thread/thread.req/thread.req.paramname/nothing_to_do.pass.cpp @@ -0,0 +1,12 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +int main() +{ +} diff --git a/test/std/thread/thread.req/thread.req.timing/nothing_to_do.pass.cpp b/test/std/thread/thread.req/thread.req.timing/nothing_to_do.pass.cpp new file mode 100644 index 000000000000..b58f5c55b643 --- /dev/null +++ b/test/std/thread/thread.req/thread.req.timing/nothing_to_do.pass.cpp @@ -0,0 +1,12 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +int main() +{ +} diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.algorithm/swap.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.algorithm/swap.pass.cpp new file mode 100644 index 000000000000..4d3a742dd168 --- /dev/null +++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.algorithm/swap.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 + +// <thread> + +// class thread + +// void swap(thread& x, thread& y); + +#include <thread> +#include <new> +#include <cstdlib> +#include <cassert> + +class G +{ + int alive_; +public: + static int n_alive; + static bool op_run; + + G() : alive_(1) {++n_alive;} + G(const G& g) : alive_(g.alive_) {++n_alive;} + ~G() {alive_ = 0; --n_alive;} + + void operator()() + { + assert(alive_ == 1); + assert(n_alive >= 1); + op_run = true; + } +}; + +int G::n_alive = 0; +bool G::op_run = false; + +int main() +{ + { + G g; + std::thread t0(g); + std::thread::id id0 = t0.get_id(); + std::thread t1; + std::thread::id id1 = t1.get_id(); + swap(t0, t1); + assert(t0.get_id() == id1); + assert(t1.get_id() == id0); + t1.join(); + } +} diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.assign/copy.fail.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.assign/copy.fail.cpp new file mode 100644 index 000000000000..7373886f6173 --- /dev/null +++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.assign/copy.fail.cpp @@ -0,0 +1,51 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// <thread> + +// class thread + +// thread& operator=(thread&& t); + +#include <thread> +#include <new> +#include <cstdlib> +#include <cassert> + +class G +{ + int alive_; +public: + static int n_alive; + static bool op_run; + + G() : alive_(1) {++n_alive;} + G(const G& g) : alive_(g.alive_) {++n_alive;} + ~G() {alive_ = 0; --n_alive;} + + void operator()() + { + assert(alive_ == 1); + assert(n_alive >= 1); + op_run = true; + } + +}; + +int G::n_alive = 0; +bool G::op_run = false; + +int main() +{ + { + std::thread t0(G()); + std::thread t1; + t1 = t0; + } +} diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.assign/move.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.assign/move.pass.cpp new file mode 100644 index 000000000000..2db9430a698d --- /dev/null +++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.assign/move.pass.cpp @@ -0,0 +1,65 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <thread> + +// class thread + +// thread& operator=(thread&& t); + +#include <thread> +#include <cassert> + +class G +{ + int alive_; +public: + static int n_alive; + static bool op_run; + + G() : alive_(1) {++n_alive;} + G(const G& g) : alive_(g.alive_) {++n_alive;} + ~G() {alive_ = 0; --n_alive;} + + void operator()(int i, double j) + { + assert(alive_ == 1); + assert(n_alive >= 1); + assert(i == 5); + assert(j == 5.5); + op_run = true; + } +}; + +int G::n_alive = 0; +bool G::op_run = false; + +int main() +{ +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + { + assert(G::n_alive == 0); + assert(!G::op_run); + { + G g; + std::thread t0(g, 5, 5.5); + std::thread::id id = t0.get_id(); + std::thread t1; + t1 = std::move(t0); + assert(t1.get_id() == id); + assert(t0.get_id() == std::thread::id()); + t1.join(); + } + assert(G::n_alive == 0); + assert(G::op_run); + } +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +} diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.assign/move2.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.assign/move2.pass.cpp new file mode 100644 index 000000000000..7198d226960a --- /dev/null +++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.assign/move2.pass.cpp @@ -0,0 +1,77 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// NOTE: std::terminate is called so the destructors are not invoked and the +// memory is not freed. This will cause ASAN to fail. +// XFAIL: asan + +// NOTE: TSAN will report this test as leaking a thread. +// XFAIL: tsan + +// <thread> + +// class thread + +// thread& operator=(thread&& t); + +#include <thread> +#include <exception> +#include <cstdlib> +#include <cassert> + +class G +{ + int alive_; +public: + static int n_alive; + static bool op_run; + + G() : alive_(1) {++n_alive;} + G(const G& g) : alive_(g.alive_) {++n_alive;} + ~G() {alive_ = 0; --n_alive;} + + void operator()() + { + assert(alive_ == 1); + assert(n_alive >= 1); + op_run = true; + } + + void operator()(int i, double j) + { + assert(alive_ == 1); + assert(n_alive >= 1); + assert(i == 5); + assert(j == 5.5); + op_run = true; + } +}; + +int G::n_alive = 0; +bool G::op_run = false; + +void f1() +{ + std::exit(0); +} + +int main() +{ + std::set_terminate(f1); + { + G g; + std::thread t0(g, 5, 5.5); + std::thread::id id = t0.get_id(); + std::thread t1; + t0 = std::move(t1); + assert(false); + } +} diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp new file mode 100644 index 000000000000..a8b4be16e631 --- /dev/null +++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp @@ -0,0 +1,154 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <thread> + +// class thread + +// template <class F, class ...Args> thread(F&& f, Args&&... args); + +// UNSUPPORTED: sanitizer-new-delete + +#include <thread> +#include <new> +#include <cstdlib> +#include <cassert> + +unsigned throw_one = 0xFFFF; + +void* operator new(std::size_t s) throw(std::bad_alloc) +{ + if (throw_one == 0) + throw std::bad_alloc(); + --throw_one; + return std::malloc(s); +} + +void operator delete(void* p) throw() +{ + std::free(p); +} + +bool f_run = false; + +void f() +{ + f_run = true; +} + +class G +{ + int alive_; +public: + static int n_alive; + static bool op_run; + + G() : alive_(1) {++n_alive;} + G(const G& g) : alive_(g.alive_) {++n_alive;} + ~G() {alive_ = 0; --n_alive;} + + void operator()() + { + assert(alive_ == 1); + assert(n_alive >= 1); + op_run = true; + } + + void operator()(int i, double j) + { + assert(alive_ == 1); + assert(n_alive >= 1); + assert(i == 5); + assert(j == 5.5); + op_run = true; + } +}; + +int G::n_alive = 0; +bool G::op_run = false; + +#ifndef _LIBCPP_HAS_NO_VARIADICS + +class MoveOnly +{ + MoveOnly(const MoveOnly&); +public: + MoveOnly() {} + MoveOnly(MoveOnly&&) {} + + void operator()(MoveOnly&&) + { + } +}; + +#endif + +int main() +{ + { + std::thread t(f); + t.join(); + assert(f_run == true); + } + f_run = false; + { + try + { + throw_one = 0; + std::thread t(f); + assert(false); + } + catch (...) + { + throw_one = 0xFFFF; + assert(!f_run); + } + } + { + assert(G::n_alive == 0); + assert(!G::op_run); + std::thread t((G())); + t.join(); + assert(G::n_alive == 0); + assert(G::op_run); + } + G::op_run = false; + { + try + { + throw_one = 0; + assert(G::n_alive == 0); + assert(!G::op_run); + std::thread t((G())); + assert(false); + } + catch (...) + { + throw_one = 0xFFFF; + assert(G::n_alive == 0); + assert(!G::op_run); + } + } +#ifndef _LIBCPP_HAS_NO_VARIADICS + { + assert(G::n_alive == 0); + assert(!G::op_run); + std::thread t(G(), 5, 5.5); + t.join(); + assert(G::n_alive == 0); + assert(G::op_run); + } + { + std::thread t = std::thread(MoveOnly(), MoveOnly()); + t.join(); + } +#endif // _LIBCPP_HAS_NO_VARIADICS +} diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/constr.fail.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/constr.fail.cpp new file mode 100644 index 000000000000..a331add96263 --- /dev/null +++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/constr.fail.cpp @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// <thread> + +// class thread +// template <class _Fp, class ..._Args, +// explicit thread(_Fp&& __f, _Args&&... __args); +// This constructor shall not participate in overload resolution +// if decay<F>::type is the same type as std::thread. + + +#include <thread> +#include <cassert> + +int main() +{ + volatile std::thread t1; + std::thread t2 ( t1, 1, 2.0 ); +} diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/copy.fail.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/copy.fail.cpp new file mode 100644 index 000000000000..f66474c93b42 --- /dev/null +++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/copy.fail.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. +// +//===----------------------------------------------------------------------===// + +// <thread> + +// class thread + +// thread(const thread&) = delete; + +#include <thread> +#include <new> +#include <cstdlib> +#include <cassert> + +class G +{ + int alive_; +public: + static int n_alive; + static bool op_run; + + G() : alive_(1) {++n_alive;} + G(const G& g) : alive_(g.alive_) {++n_alive;} + ~G() {alive_ = 0; --n_alive;} + + void operator()() + { + assert(alive_ == 1); + assert(n_alive >= 1); + op_run = true; + } + + void operator()(int i, double j) + { + assert(alive_ == 1); + assert(n_alive >= 1); + assert(i == 5); + assert(j == 5.5); + op_run = true; + } +}; + +int G::n_alive = 0; +bool G::op_run = false; + +int main() +{ + { + assert(G::n_alive == 0); + assert(!G::op_run); + std::thread t0(G(), 5, 5.5); + std::thread::id id = t0.get_id(); + std::thread t1 = t0; + assert(t1.get_id() == id); + assert(t0.get_id() == std::thread::id()); + t1.join(); + assert(G::n_alive == 0); + assert(G::op_run); + } +} diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/default.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/default.pass.cpp new file mode 100644 index 000000000000..64d5a935ba55 --- /dev/null +++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/default.pass.cpp @@ -0,0 +1,25 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <thread> + +// class thread + +// thread(); + +#include <thread> +#include <cassert> + +int main() +{ + std::thread t; + assert(t.get_id() == std::thread::id()); +} diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/move.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/move.pass.cpp new file mode 100644 index 000000000000..e88304ec8da9 --- /dev/null +++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/move.pass.cpp @@ -0,0 +1,72 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <thread> + +// class thread + +// thread(thread&& t); + +#include <thread> +#include <new> +#include <cstdlib> +#include <cassert> + +class G +{ + int alive_; +public: + static int n_alive; + static bool op_run; + + G() : alive_(1) {++n_alive;} + G(const G& g) : alive_(g.alive_) {++n_alive;} + ~G() {alive_ = 0; --n_alive;} + + void operator()() + { + assert(alive_ == 1); + assert(n_alive >= 1); + op_run = true; + } + + void operator()(int i, double j) + { + assert(alive_ == 1); + assert(n_alive >= 1); + assert(i == 5); + assert(j == 5.5); + op_run = true; + } +}; + +int G::n_alive = 0; +bool G::op_run = false; + +int main() +{ +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + { + G g; + assert(G::n_alive == 1); + assert(!G::op_run); + std::thread t0(g, 5, 5.5); + std::thread::id id = t0.get_id(); + std::thread t1 = std::move(t0); + assert(t1.get_id() == id); + assert(t0.get_id() == std::thread::id()); + t1.join(); + assert(G::n_alive == 1); + assert(G::op_run); + } + assert(G::n_alive == 0); +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +} diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.destr/dtor.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.destr/dtor.pass.cpp new file mode 100644 index 000000000000..ddf96d095730 --- /dev/null +++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.destr/dtor.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 + +// NOTE: TSAN will report this test as leaking a thread. +// XFAIL: tsan + +// <thread> + +// class thread + +// ~thread(); + +#include <thread> +#include <new> +#include <cstdlib> +#include <cassert> + +class G +{ + int alive_; +public: + static int n_alive; + static bool op_run; + + G() : alive_(1) {++n_alive;} + G(const G& g) : alive_(g.alive_) {++n_alive;} + ~G() {alive_ = 0; --n_alive;} + + void operator()() + { + assert(alive_ == 1); + assert(n_alive >= 1); + op_run = true; + } +}; + +int G::n_alive = 0; +bool G::op_run = false; + +void f1() +{ + std::exit(0); +} + +int main() +{ + std::set_terminate(f1); + { + assert(G::n_alive == 0); + assert(!G::op_run); + G g; + { + std::thread t(g); + std::this_thread::sleep_for(std::chrono::milliseconds(250)); + } + } + assert(false); +} diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/assign.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/assign.pass.cpp new file mode 100644 index 000000000000..585f7ea98a03 --- /dev/null +++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/assign.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 + +// <thread> + +// class thread::id + +// id& operator=(const id&) = default; + +#include <thread> +#include <cassert> + +int main() +{ + std::thread::id id0; + std::thread::id id1; + id1 = id0; + assert(id1 == id0); + id1 = std::this_thread::get_id(); + assert(id1 != id0); +} diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/copy.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/copy.pass.cpp new file mode 100644 index 000000000000..e8c38016b288 --- /dev/null +++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/copy.pass.cpp @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <thread> + +// class thread::id + +// id(const id&) = default; + +#include <thread> +#include <cassert> + +int main() +{ + std::thread::id id0; + std::thread::id id1 = id0; + assert(id1 == id0); +} diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/default.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/default.pass.cpp new file mode 100644 index 000000000000..0037deb1dd65 --- /dev/null +++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/default.pass.cpp @@ -0,0 +1,25 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <thread> + +// class thread::id + +// id(); + +#include <thread> +#include <cassert> + +int main() +{ + std::thread::id id; + assert(id == std::thread::id()); +} diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/eq.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/eq.pass.cpp new file mode 100644 index 000000000000..6dd4c3ec4f57 --- /dev/null +++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/eq.pass.cpp @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <thread> + +// class thread::id + +// bool operator==(thread::id x, thread::id y); +// bool operator!=(thread::id x, thread::id y); + +#include <thread> +#include <cassert> + +int main() +{ + std::thread::id id0; + std::thread::id id1; + id1 = id0; + assert( (id1 == id0)); + assert(!(id1 != id0)); + id1 = std::this_thread::get_id(); + assert(!(id1 == id0)); + assert( (id1 != id0)); +} diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/lt.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/lt.pass.cpp new file mode 100644 index 000000000000..de52b1d00cdf --- /dev/null +++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/lt.pass.cpp @@ -0,0 +1,43 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <thread> + +// class thread::id + +// bool operator< (thread::id x, thread::id y); +// bool operator<=(thread::id x, thread::id y); +// bool operator> (thread::id x, thread::id y); +// bool operator>=(thread::id x, thread::id y); + +#include <thread> +#include <cassert> + +int main() +{ + std::thread::id id0; + std::thread::id id1; + std::thread::id id2 = std::this_thread::get_id(); + assert(!(id0 < id1)); + assert( (id0 <= id1)); + assert(!(id0 > id1)); + assert( (id0 >= id1)); + assert(!(id0 == id2)); + if (id0 < id2) { + assert( (id0 <= id2)); + assert(!(id0 > id2)); + assert(!(id0 >= id2)); + } else { + assert(!(id0 <= id2)); + assert( (id0 > id2)); + assert( (id0 >= id2)); + } +} diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/stream.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/stream.pass.cpp new file mode 100644 index 000000000000..126965fe3fc3 --- /dev/null +++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/stream.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 + +// <thread> + +// class thread::id + +// template<class charT, class traits> +// basic_ostream<charT, traits>& +// operator<<(basic_ostream<charT, traits>& out, thread::id id); + +#include <thread> +#include <sstream> +#include <cassert> + +int main() +{ + std::thread::id id0 = std::this_thread::get_id(); + std::ostringstream os; + os << id0; +} diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/thread_id.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/thread_id.pass.cpp new file mode 100644 index 000000000000..106c69e2e4a1 --- /dev/null +++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/thread_id.pass.cpp @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <functional> + +// template <class T> +// struct hash +// : public unary_function<T, size_t> +// { +// size_t operator()(T val) const; +// }; + +// Not very portable + +#include <thread> +#include <cassert> + +int main() +{ + std::thread::id id1; + std::thread::id id2 = std::this_thread::get_id(); + typedef std::hash<std::thread::id> H; + static_assert((std::is_same<typename H::argument_type, std::thread::id>::value), "" ); + static_assert((std::is_same<typename H::result_type, std::size_t>::value), "" ); + H h; + assert(h(id1) != h(id2)); +} diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/detach.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/detach.pass.cpp new file mode 100644 index 000000000000..f4a4d1f777f1 --- /dev/null +++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/detach.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 + +// <thread> + +// class thread + +// void detach(); + +#include <thread> +#include <atomic> +#include <cassert> + +std::atomic_bool done = ATOMIC_VAR_INIT(false); + +class G +{ + int alive_; + bool done_; +public: + static int n_alive; + static bool op_run; + + G() : alive_(1), done_(false) + { + ++n_alive; + } + + G(const G& g) : alive_(g.alive_), done_(false) + { + ++n_alive; + } + ~G() + { + alive_ = 0; + --n_alive; + if (done_) done = true; + } + + void operator()() + { + assert(alive_ == 1); + assert(n_alive >= 1); + op_run = true; + done_ = true; + } +}; + +int G::n_alive = 0; +bool G::op_run = false; + +int main() +{ + { + G g; + std::thread t0(g); + assert(t0.joinable()); + t0.detach(); + assert(!t0.joinable()); + while (!done) {} + assert(G::op_run); + assert(G::n_alive == 1); + } + assert(G::n_alive == 0); +} diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/get_id.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/get_id.pass.cpp new file mode 100644 index 000000000000..5cca7b0b66b8 --- /dev/null +++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/get_id.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 + +// <thread> + +// class thread + +// id get_id() const; + +#include <thread> +#include <new> +#include <cstdlib> +#include <cassert> + +class G +{ + int alive_; +public: + static int n_alive; + static bool op_run; + + G() : alive_(1) {++n_alive;} + G(const G& g) : alive_(g.alive_) {++n_alive;} + ~G() {alive_ = 0; --n_alive;} + + void operator()() + { + assert(alive_ == 1); + assert(n_alive >= 1); + op_run = true; + } +}; + +int G::n_alive = 0; +bool G::op_run = false; + +int main() +{ + { + G g; + std::thread t0(g); + std::thread::id id0 = t0.get_id(); + std::thread t1; + std::thread::id id1 = t1.get_id(); + assert(t0.get_id() != id1); + assert(t1.get_id() == std::thread::id()); + t0.join(); + } +} diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/join.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/join.pass.cpp new file mode 100644 index 000000000000..0512e49dcb33 --- /dev/null +++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/join.pass.cpp @@ -0,0 +1,54 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <thread> + +// class thread + +// void join(); + +#include <thread> +#include <new> +#include <cstdlib> +#include <cassert> + +class G +{ + int alive_; +public: + static int n_alive; + static bool op_run; + + G() : alive_(1) {++n_alive;} + G(const G& g) : alive_(g.alive_) {++n_alive;} + ~G() {alive_ = 0; --n_alive;} + + void operator()() + { + assert(alive_ == 1); + assert(n_alive >= 1); + op_run = true; + } +}; + +int G::n_alive = 0; +bool G::op_run = false; + +int main() +{ + { + G g; + std::thread t0(g); + assert(t0.joinable()); + t0.join(); + assert(!t0.joinable()); + } +} diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/joinable.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/joinable.pass.cpp new file mode 100644 index 000000000000..b97839c32184 --- /dev/null +++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/joinable.pass.cpp @@ -0,0 +1,54 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <thread> + +// class thread + +// bool joinable() const; + +#include <thread> +#include <new> +#include <cstdlib> +#include <cassert> + +class G +{ + int alive_; +public: + static int n_alive; + static bool op_run; + + G() : alive_(1) {++n_alive;} + G(const G& g) : alive_(g.alive_) {++n_alive;} + ~G() {alive_ = 0; --n_alive;} + + void operator()() + { + assert(alive_ == 1); + assert(n_alive >= 1); + op_run = true; + } +}; + +int G::n_alive = 0; +bool G::op_run = false; + +int main() +{ + { + G g; + std::thread t0(g); + assert(t0.joinable()); + t0.join(); + assert(!t0.joinable()); + } +} diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/native_handle.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/native_handle.pass.cpp new file mode 100644 index 000000000000..c8807a965c44 --- /dev/null +++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/native_handle.pass.cpp @@ -0,0 +1,54 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <thread> + +// class thread + +// native_handle_type native_handle(); + +#include <thread> +#include <new> +#include <cstdlib> +#include <cassert> + +class G +{ + int alive_; +public: + static int n_alive; + static bool op_run; + + G() : alive_(1) {++n_alive;} + G(const G& g) : alive_(g.alive_) {++n_alive;} + ~G() {alive_ = 0; --n_alive;} + + void operator()() + { + assert(alive_ == 1); + assert(n_alive >= 1); + op_run = true; + } +}; + +int G::n_alive = 0; +bool G::op_run = false; + +int main() +{ + { + G g; + std::thread t0(g); + pthread_t pid = t0.native_handle(); + assert(pid != 0); + t0.join(); + } +} diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/swap.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/swap.pass.cpp new file mode 100644 index 000000000000..49d4618e86ad --- /dev/null +++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/swap.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 + +// <thread> + +// class thread + +// void swap(thread& t); + +#include <thread> +#include <new> +#include <cstdlib> +#include <cassert> + +class G +{ + int alive_; +public: + static int n_alive; + static bool op_run; + + G() : alive_(1) {++n_alive;} + G(const G& g) : alive_(g.alive_) {++n_alive;} + ~G() {alive_ = 0; --n_alive;} + + void operator()() + { + assert(alive_ == 1); + assert(n_alive >= 1); + op_run = true; + } +}; + +int G::n_alive = 0; +bool G::op_run = false; + +int main() +{ + { + G g; + std::thread t0(g); + std::thread::id id0 = t0.get_id(); + std::thread t1; + std::thread::id id1 = t1.get_id(); + t0.swap(t1); + assert(t0.get_id() == id1); + assert(t1.get_id() == id0); + t1.join(); + } +} diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.static/hardware_concurrency.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.static/hardware_concurrency.pass.cpp new file mode 100644 index 000000000000..4d1ffad45937 --- /dev/null +++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.static/hardware_concurrency.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 + +// <thread> + +// class thread + +// unsigned hardware_concurrency(); + +#include <thread> +#include <cassert> + +int main() +{ + assert(std::thread::hardware_concurrency() > 0); +} diff --git a/test/std/thread/thread.threads/thread.thread.class/types.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/types.pass.cpp new file mode 100644 index 000000000000..a5bf77031cca --- /dev/null +++ b/test/std/thread/thread.threads/thread.thread.class/types.pass.cpp @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <thread> + +// class thread +// { +// public: +// typedef pthread_t native_handle_type; +// ... +// }; + +#include <thread> +#include <type_traits> + +int main() +{ + static_assert((std::is_same<std::thread::native_handle_type, pthread_t>::value), ""); +} diff --git a/test/std/thread/thread.threads/thread.thread.this/get_id.pass.cpp b/test/std/thread/thread.threads/thread.thread.this/get_id.pass.cpp new file mode 100644 index 000000000000..3b4b7823a831 --- /dev/null +++ b/test/std/thread/thread.threads/thread.thread.this/get_id.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 + +// <thread> + +// thread::id this_thread::get_id(); + +#include <thread> +#include <cassert> + +int main() +{ + std::thread::id id = std::this_thread::get_id(); + assert(id != std::thread::id()); +} diff --git a/test/std/thread/thread.threads/thread.thread.this/sleep_for.pass.cpp b/test/std/thread/thread.threads/thread.thread.this/sleep_for.pass.cpp new file mode 100644 index 000000000000..27e1d2a1d42f --- /dev/null +++ b/test/std/thread/thread.threads/thread.thread.this/sleep_for.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 + +// <thread> + +// template <class Rep, class Period> +// void sleep_for(const chrono::duration<Rep, Period>& rel_time); + +#include <thread> +#include <cstdlib> +#include <cassert> +#include <cstring> +#include <signal.h> +#include <sys/time.h> + +void sig_action(int) {} + +int main() +{ + int ec; + struct sigaction action; + action.sa_handler = &sig_action; + sigemptyset(&action.sa_mask); + action.sa_flags = 0; + + ec = sigaction(SIGALRM, &action, nullptr); + assert(!ec); + + struct itimerval it; + std::memset(&it, 0, sizeof(itimerval)); + it.it_value.tv_sec = 0; + it.it_value.tv_usec = 250000; + // This will result in a SIGALRM getting fired resulting in the nanosleep + // inside sleep_for getting EINTR. + ec = setitimer(ITIMER_REAL, &it, nullptr); + assert(!ec); + + typedef std::chrono::system_clock Clock; + typedef Clock::time_point time_point; + typedef Clock::duration duration; + std::chrono::milliseconds ms(500); + time_point t0 = Clock::now(); + std::this_thread::sleep_for(ms); + time_point t1 = Clock::now(); + std::chrono::nanoseconds ns = (t1 - t0) - ms; + std::chrono::nanoseconds err = 5 * ms / 100; + // The time slept is within 5% of 500ms + assert(std::abs(ns.count()) < err.count()); +} diff --git a/test/std/thread/thread.threads/thread.thread.this/sleep_until.pass.cpp b/test/std/thread/thread.threads/thread.thread.this/sleep_until.pass.cpp new file mode 100644 index 000000000000..9f3941b93adf --- /dev/null +++ b/test/std/thread/thread.threads/thread.thread.this/sleep_until.pass.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <thread> + +// template <class Clock, class Duration> +// void sleep_until(const chrono::time_point<Clock, Duration>& abs_time); + +#include <thread> +#include <cstdlib> +#include <cassert> + +int main() +{ + typedef std::chrono::system_clock Clock; + typedef Clock::time_point time_point; + typedef Clock::duration duration; + std::chrono::milliseconds ms(500); + time_point t0 = Clock::now(); + std::this_thread::sleep_until(t0 + ms); + time_point t1 = Clock::now(); + std::chrono::nanoseconds ns = (t1 - t0) - ms; + std::chrono::nanoseconds err = 5 * ms / 100; + // The time slept is within 5% of 500ms + assert(std::abs(ns.count()) < err.count()); +} diff --git a/test/std/thread/thread.threads/thread.thread.this/yield.pass.cpp b/test/std/thread/thread.threads/thread.thread.this/yield.pass.cpp new file mode 100644 index 000000000000..daf5b0cf7abf --- /dev/null +++ b/test/std/thread/thread.threads/thread.thread.this/yield.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 + +// <thread> + +// void this_thread::yield(); + +#include <thread> +#include <cassert> + +int main() +{ + std::this_thread::yield(); +} diff --git a/test/std/thread/thread.threads/version.pass.cpp b/test/std/thread/thread.threads/version.pass.cpp new file mode 100644 index 000000000000..d16b0eb06842 --- /dev/null +++ b/test/std/thread/thread.threads/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 + +// <thread> + +#include <thread> + +#ifndef _LIBCPP_VERSION +#error _LIBCPP_VERSION not defined +#endif + +int main() +{ +} |