From 46c38761886fb66b8648ab018ec4cfa04c3b8c7a Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Mon, 24 Feb 2020 10:09:29 -0500 Subject: [PATCH] [libc++] Add availability markup for the C++20 Synchronization Library on Apple --- libcxx/include/__config | 3 +- libcxx/include/__threading_support | 3 +- libcxx/include/atomic | 59 ++++++++-------- libcxx/include/barrier | 32 ++++----- libcxx/include/latch | 6 +- libcxx/include/semaphore | 16 ++--- .../libcxx/thread/atomic.availability.fail.cpp | 81 ++++++++++++++++++++++ .../libcxx/thread/barrier.availability.fail.cpp | 44 ++++++++++++ .../test/libcxx/thread/latch.availability.fail.cpp | 27 ++++++++ .../libcxx/thread/semaphore.availability.fail.cpp | 52 ++++++++++++++ 10 files changed, 266 insertions(+), 57 deletions(-) create mode 100644 libcxx/test/libcxx/thread/atomic.availability.fail.cpp create mode 100644 libcxx/test/libcxx/thread/barrier.availability.fail.cpp create mode 100644 libcxx/test/libcxx/thread/latch.availability.fail.cpp create mode 100644 libcxx/test/libcxx/thread/semaphore.availability.fail.cpp diff --git a/libcxx/include/__config b/libcxx/include/__config index 9bd7fc9..ce7a935 100644 --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -1374,6 +1374,7 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( // Decide whether to use availability macros. #if !defined(_LIBCPP_BUILDING_LIBRARY) && \ + !defined(_LIBCXXABI_BUILDING_LIBRARY) && \ !defined(_LIBCPP_DISABLE_AVAILABILITY) && \ __has_feature(attribute_availability_with_strict) && \ __has_feature(attribute_availability_in_templates) && \ @@ -1438,7 +1439,7 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( # define _LIBCPP_AVAILABILITY_TO_CHARS \ _LIBCPP_AVAILABILITY_FILESYSTEM # define _LIBCPP_AVAILABILITY_SYNC \ - /*FIXME:mark this as unavailable on Apple platforms*/ + __attribute__((unavailable)) #else # define _LIBCPP_AVAILABILITY_SHARED_MUTEX # define _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS diff --git a/libcxx/include/__threading_support b/libcxx/include/__threading_support index e9c727e..8e986c8 100644 --- a/libcxx/include/__threading_support +++ b/libcxx/include/__threading_support @@ -286,7 +286,7 @@ struct __libcpp_timed_backoff_policy { }; template -_LIBCPP_INLINE_VISIBILITY +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY bool __libcpp_thread_poll_with_backoff( _Fn && __f, _BFn && __bf, chrono::nanoseconds __max_elapsed = chrono::nanoseconds::zero()); @@ -694,6 +694,7 @@ bool __libcpp_timed_backoff_policy::operator()(chrono::nanoseconds __elapsed) co static _LIBCPP_CONSTEXPR const int __libcpp_polling_count = 64; template +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY bool __libcpp_thread_poll_with_backoff(_Fn && __f, _BFn && __bf, chrono::nanoseconds __max_elapsed) { auto const __start = chrono::high_resolution_clock::now(); diff --git a/libcxx/include/atomic b/libcxx/include/atomic index 56d8026..c25bea8 100644 --- a/libcxx/include/atomic +++ b/libcxx/include/atomic @@ -1485,6 +1485,7 @@ template struct __libcpp_atomic_wait_backoff_impl { _Atp* __a; _Fn __test_fn; + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY bool operator()(chrono::nanoseconds __elapsed) const { if(__elapsed > chrono::microseconds(64)) @@ -1503,6 +1504,7 @@ struct __libcpp_atomic_wait_backoff_impl { }; template +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Fn && __test_fn) { __libcpp_atomic_wait_backoff_impl<_Atp, typename decay<_Fn>::type> __backoff_fn = {__a, __test_fn}; @@ -1535,6 +1537,7 @@ struct __cxx_atomic_wait_test_fn_impl { }; template +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Tp const __val, memory_order __order) { __cxx_atomic_wait_test_fn_impl<_Atp, _Tp> __test_fn = {__a, __val, __order}; @@ -1623,17 +1626,17 @@ struct __atomic_base // false memory_order __m = memory_order_seq_cst) _NOEXCEPT {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);} - _LIBCPP_INLINE_VISIBILITY void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT {__cxx_atomic_wait(&__a_, __v, __m);} - _LIBCPP_INLINE_VISIBILITY void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT {__cxx_atomic_wait(&__a_, __v, __m);} - _LIBCPP_INLINE_VISIBILITY void notify_one() volatile _NOEXCEPT + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() volatile _NOEXCEPT {__cxx_atomic_notify_one(&__a_);} - _LIBCPP_INLINE_VISIBILITY void notify_one() _NOEXCEPT + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() _NOEXCEPT {__cxx_atomic_notify_one(&__a_);} - _LIBCPP_INLINE_VISIBILITY void notify_all() volatile _NOEXCEPT + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() volatile _NOEXCEPT {__cxx_atomic_notify_all(&__a_);} - _LIBCPP_INLINE_VISIBILITY void notify_all() _NOEXCEPT + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() _NOEXCEPT {__cxx_atomic_notify_all(&__a_);} _LIBCPP_INLINE_VISIBILITY @@ -2059,7 +2062,7 @@ atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, _Tp* __e, // atomic_wait template -_LIBCPP_INLINE_VISIBILITY +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void atomic_wait(const volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __v) _NOEXCEPT { @@ -2067,7 +2070,7 @@ void atomic_wait(const volatile atomic<_Tp>* __o, } template -_LIBCPP_INLINE_VISIBILITY +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void atomic_wait(const atomic<_Tp>* __o, typename atomic<_Tp>::value_type __v) _NOEXCEPT { @@ -2077,7 +2080,7 @@ void atomic_wait(const atomic<_Tp>* __o, // atomic_wait_explicit template -_LIBCPP_INLINE_VISIBILITY +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void atomic_wait_explicit(const volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __v, memory_order __m) _NOEXCEPT @@ -2087,7 +2090,7 @@ void atomic_wait_explicit(const volatile atomic<_Tp>* __o, } template -_LIBCPP_INLINE_VISIBILITY +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void atomic_wait_explicit(const atomic<_Tp>* __o, typename atomic<_Tp>::value_type __v, memory_order __m) _NOEXCEPT @@ -2099,13 +2102,13 @@ void atomic_wait_explicit(const atomic<_Tp>* __o, // atomic_notify_one template -_LIBCPP_INLINE_VISIBILITY +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void atomic_notify_one(volatile atomic<_Tp>* __o) _NOEXCEPT { __o->notify_one(); } template -_LIBCPP_INLINE_VISIBILITY +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT { __o->notify_one(); @@ -2114,13 +2117,13 @@ void atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT // atomic_notify_one template -_LIBCPP_INLINE_VISIBILITY +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void atomic_notify_all(volatile atomic<_Tp>* __o) _NOEXCEPT { __o->notify_all(); } template -_LIBCPP_INLINE_VISIBILITY +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void atomic_notify_all(atomic<_Tp>* __o) _NOEXCEPT { __o->notify_all(); @@ -2478,22 +2481,22 @@ typedef struct atomic_flag void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void wait(bool __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() volatile _NOEXCEPT {__cxx_atomic_notify_one(&__a_);} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() _NOEXCEPT {__cxx_atomic_notify_one(&__a_);} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() volatile _NOEXCEPT {__cxx_atomic_notify_all(&__a_);} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() _NOEXCEPT {__cxx_atomic_notify_all(&__a_);} @@ -2603,21 +2606,21 @@ atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT __o->clear(__m); } -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC void atomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT { __o->wait(__v); } -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC void atomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT { __o->wait(__v); } -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC void atomic_flag_wait_explicit(const volatile atomic_flag* __o, bool __v, memory_order __m) _NOEXCEPT @@ -2625,7 +2628,7 @@ atomic_flag_wait_explicit(const volatile atomic_flag* __o, __o->wait(__v, __m); } -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC void atomic_flag_wait_explicit(const atomic_flag* __o, bool __v, memory_order __m) _NOEXCEPT @@ -2633,28 +2636,28 @@ atomic_flag_wait_explicit(const atomic_flag* __o, __o->wait(__v, __m); } -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC void atomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT { __o->notify_one(); } -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC void atomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT { __o->notify_one(); } -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC void atomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT { __o->notify_all(); } -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC void atomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT { diff --git a/libcxx/include/barrier b/libcxx/include/barrier index 5ef8b78..58e3eef 100644 --- a/libcxx/include/barrier +++ b/libcxx/include/barrier @@ -104,7 +104,7 @@ class __barrier_base { ptrdiff_t __expected; unique_ptr<__barrier_algorithm_base, - decltype(&__destroy_barrier_algorithm_base)> __base; + void (*)(__barrier_algorithm_base*)> __base; __atomic_base __expected_adjustment; _CompletionF __completion; __atomic_base<__barrier_phase_t> __phase; @@ -116,14 +116,14 @@ public: return numeric_limits::max(); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY __barrier_base(ptrdiff_t __expected, _CompletionF __completion = _CompletionF()) : __expected(__expected), __base(__construct_barrier_algorithm_base(this->__expected), &__destroy_barrier_algorithm_base), __expected_adjustment(0), __completion(move(__completion)), __phase(0) { } - [[nodiscard]] _LIBCPP_INLINE_VISIBILITY + [[nodiscard]] _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY arrival_token arrive(ptrdiff_t update) { auto const __old_phase = __phase.load(memory_order_relaxed); @@ -137,7 +137,7 @@ public: } return __old_phase; } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void wait(arrival_token&& __old_phase) const { auto const __test_fn = [=]() -> bool { @@ -145,7 +145,7 @@ public: }; __libcpp_thread_poll_with_backoff(__test_fn, __libcpp_timed_backoff_policy()); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void arrive_and_drop() { __expected_adjustment.fetch_sub(1, memory_order_relaxed); @@ -187,7 +187,7 @@ public: : __expected(__expected), __arrived(__expected), __completion(move(__completion)), __phase(false) { } - [[nodiscard]] _LIBCPP_INLINE_VISIBILITY + [[nodiscard]] _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY arrival_token arrive(ptrdiff_t update) { auto const __old_phase = __phase.load(memory_order_relaxed); @@ -201,12 +201,12 @@ public: } return __old_phase; } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void wait(arrival_token&& __old_phase) const { __phase.wait(__old_phase, memory_order_acquire); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void arrive_and_drop() { __expected.fetch_sub(1, memory_order_relaxed); @@ -244,7 +244,7 @@ public: : __phase_arrived_expected(__init(__count)) { } - [[nodiscard]] inline _LIBCPP_INLINE_VISIBILITY + [[nodiscard]] inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY arrival_token arrive(ptrdiff_t update) { auto const __inc = __arrived_unit * update; @@ -255,7 +255,7 @@ public: } return __old & __phase_bit; } - inline _LIBCPP_INLINE_VISIBILITY + inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void wait(arrival_token&& __phase) const { auto const __test_fn = [=]() -> bool { @@ -264,7 +264,7 @@ public: }; __libcpp_thread_poll_with_backoff(__test_fn, __libcpp_timed_backoff_policy()); } - inline _LIBCPP_INLINE_VISIBILITY + inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void arrive_and_drop() { __phase_arrived_expected.fetch_add(__expected_unit, memory_order_relaxed); @@ -285,7 +285,7 @@ public: return __barrier_base<_CompletionF>::max(); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY barrier(ptrdiff_t __count, _CompletionF __completion = _CompletionF()) : __b(__count, std::move(__completion)) { } @@ -293,22 +293,22 @@ public: barrier(barrier const&) = delete; barrier& operator=(barrier const&) = delete; - [[nodiscard]] _LIBCPP_INLINE_VISIBILITY + [[nodiscard]] _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY arrival_token arrive(ptrdiff_t update = 1) { return __b.arrive(update); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void wait(arrival_token&& __phase) const { __b.wait(std::move(__phase)); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void arrive_and_wait() { wait(arrive()); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void arrive_and_drop() { __b.arrive_and_drop(); diff --git a/libcxx/include/latch b/libcxx/include/latch index c83f6bf..f669f58 100644 --- a/libcxx/include/latch +++ b/libcxx/include/latch @@ -69,7 +69,7 @@ public: latch(const latch&) = delete; latch& operator=(const latch&) = delete; - inline _LIBCPP_INLINE_VISIBILITY + inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void count_down(ptrdiff_t __update = 1) { auto const __old = __a.fetch_sub(__update, memory_order_release); @@ -81,7 +81,7 @@ public: { return 0 == __a.load(memory_order_acquire); } - inline _LIBCPP_INLINE_VISIBILITY + inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void wait() const { auto const __test_fn = [=]() -> bool { @@ -89,7 +89,7 @@ public: }; __cxx_atomic_wait(&__a.__a_, __test_fn); } - inline _LIBCPP_INLINE_VISIBILITY + inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void arrive_and_wait(ptrdiff_t __update = 1) { count_down(__update); diff --git a/libcxx/include/semaphore b/libcxx/include/semaphore index 8a2e778..447bc2f 100644 --- a/libcxx/include/semaphore +++ b/libcxx/include/semaphore @@ -82,7 +82,7 @@ public: __atomic_semaphore_base(ptrdiff_t __count) : __a(__count) { } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void release(ptrdiff_t __update = 1) { if(0 < __a.fetch_add(__update, memory_order_release)) @@ -92,7 +92,7 @@ public: else __a.notify_one(); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void acquire() { auto const __test_fn = [=]() -> bool { @@ -102,7 +102,7 @@ public: __cxx_atomic_wait(&__a.__a_, __test_fn); } template - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY bool try_acquire_for(chrono::duration const& __rel_time) { auto const __test_fn = [=]() -> bool { @@ -193,29 +193,29 @@ public: counting_semaphore(const counting_semaphore&) = delete; counting_semaphore& operator=(const counting_semaphore&) = delete; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void release(ptrdiff_t __update = 1) { __semaphore.release(__update); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void acquire() { __semaphore.acquire(); } template - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY bool try_acquire_for(chrono::duration const& __rel_time) { return __semaphore.try_acquire_for(chrono::duration_cast(__rel_time)); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY bool try_acquire() { return try_acquire_for(chrono::nanoseconds::zero()); } template - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY bool try_acquire_until(chrono::time_point const& __abs_time) { auto const current = Clock::now(); diff --git a/libcxx/test/libcxx/thread/atomic.availability.fail.cpp b/libcxx/test/libcxx/thread/atomic.availability.fail.cpp new file mode 100644 index 0000000..323a53b --- /dev/null +++ b/libcxx/test/libcxx/thread/atomic.availability.fail.cpp @@ -0,0 +1,81 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 +// REQUIRES: verify-support +// REQUIRES: with_system_cxx_lib=macosx +// REQUIRES: availability=macosx10.7 || availability=macosx10.8 || availability=macosx10.9 || availability=macosx10.10 || availability=macosx10.11 || availability=macosx10.12 || availability=macosx10.13 || availability=macosx10.14 || availability=macosx10.15 + +// Test the availability markup on the C++20 Synchronization Library +// additions to . + +#include + + +int main(int, char**) +{ + { + std::atomic i(3); + std::memory_order m = std::memory_order_relaxed; + + i.wait(4); // expected-error {{is unavailable}} + i.wait(4, m); // expected-error {{is unavailable}} + i.notify_one(); // expected-error {{is unavailable}} + i.notify_all(); // expected-error {{is unavailable}} + + std::atomic_wait(&i, 4); // expected-error {{is unavailable}} + std::atomic_wait_explicit(&i, 4, m); // expected-error {{is unavailable}} + std::atomic_notify_one(&i); // expected-error {{is unavailable}} + std::atomic_notify_all(&i); // expected-error {{is unavailable}} + } + + { + std::atomic volatile i(3); + std::memory_order m = std::memory_order_relaxed; + + i.wait(4); // expected-error {{is unavailable}} + i.wait(4, m); // expected-error {{is unavailable}} + i.notify_one(); // expected-error {{is unavailable}} + i.notify_all(); // expected-error {{is unavailable}} + + std::atomic_wait(&i, 4); // expected-error {{is unavailable}} + std::atomic_wait_explicit(&i, 4, m); // expected-error {{is unavailable}} + std::atomic_notify_one(&i); // expected-error {{is unavailable}} + std::atomic_notify_all(&i); // expected-error {{is unavailable}} + } + + { + std::atomic_flag flag; + bool b = false; + std::memory_order m = std::memory_order_relaxed; + flag.wait(b); // expected-error {{is unavailable}} + flag.wait(b, m); // expected-error {{is unavailable}} + flag.notify_one(); // expected-error {{is unavailable}} + flag.notify_all(); // expected-error {{is unavailable}} + + std::atomic_flag_wait(&flag, b); // expected-error {{is unavailable}} + std::atomic_flag_wait_explicit(&flag, b, m); // expected-error {{is unavailable}} + std::atomic_flag_notify_one(&flag); // expected-error {{is unavailable}} + std::atomic_flag_notify_all(&flag); // expected-error {{is unavailable}} + } + + { + std::atomic_flag volatile flag; + bool b = false; + std::memory_order m = std::memory_order_relaxed; + flag.wait(b); // expected-error {{is unavailable}} + flag.wait(b, m); // expected-error {{is unavailable}} + flag.notify_one(); // expected-error {{is unavailable}} + flag.notify_all(); // expected-error {{is unavailable}} + + std::atomic_flag_wait(&flag, b); // expected-error {{is unavailable}} + std::atomic_flag_wait_explicit(&flag, b, m); // expected-error {{is unavailable}} + std::atomic_flag_notify_one(&flag); // expected-error {{is unavailable}} + std::atomic_flag_notify_all(&flag); // expected-error {{is unavailable}} + } +} diff --git a/libcxx/test/libcxx/thread/barrier.availability.fail.cpp b/libcxx/test/libcxx/thread/barrier.availability.fail.cpp new file mode 100644 index 0000000..bb6e980 --- /dev/null +++ b/libcxx/test/libcxx/thread/barrier.availability.fail.cpp @@ -0,0 +1,44 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 +// REQUIRES: verify-support +// REQUIRES: with_system_cxx_lib=macosx +// REQUIRES: availability=macosx10.7 || availability=macosx10.8 || availability=macosx10.9 || availability=macosx10.10 || availability=macosx10.11 || availability=macosx10.12 || availability=macosx10.13 || availability=macosx10.14 || availability=macosx10.15 + +// Test the availability markup on std::barrier. + +#include +#include + +struct CompletionF { + void operator()() { } +}; + +int main(int, char**) +{ + // Availability markup on std::barrier<> + { + std::barrier<> b(10); // expected-error {{is unavailable}} + auto token = b.arrive(); // expected-error {{is unavailable}} + (void)b.arrive(10); // expected-error {{is unavailable}} + b.wait(std::move(token)); // expected-error {{is unavailable}} + b.arrive_and_wait(); // expected-error {{is unavailable}} + b.arrive_and_drop(); // expected-error {{is unavailable}} + } + + // Availability markup on std::barrier with non-default CompletionF + { + std::barrier b(10); // expected-error {{is unavailable}} + auto token = b.arrive(); // expected-error {{is unavailable}} + (void)b.arrive(10); // expected-error {{is unavailable}} + b.wait(std::move(token)); // expected-error {{is unavailable}} + b.arrive_and_wait(); // expected-error {{is unavailable}} + b.arrive_and_drop(); // expected-error {{is unavailable}} + } +} diff --git a/libcxx/test/libcxx/thread/latch.availability.fail.cpp b/libcxx/test/libcxx/thread/latch.availability.fail.cpp new file mode 100644 index 0000000..7252376 --- /dev/null +++ b/libcxx/test/libcxx/thread/latch.availability.fail.cpp @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 +// REQUIRES: verify-support +// REQUIRES: with_system_cxx_lib=macosx +// REQUIRES: availability=macosx10.7 || availability=macosx10.8 || availability=macosx10.9 || availability=macosx10.10 || availability=macosx10.11 || availability=macosx10.12 || availability=macosx10.13 || availability=macosx10.14 || availability=macosx10.15 + +// Test the availability markup on std::latch. + +#include + + +int main(int, char**) +{ + std::latch latch(10); + latch.count_down(); // expected-error {{is unavailable}} + latch.count_down(3); // expected-error {{is unavailable}} + latch.wait(); // expected-error {{is unavailable}} + latch.arrive_and_wait(); // expected-error {{is unavailable}} + latch.arrive_and_wait(3); // expected-error {{is unavailable}} +} diff --git a/libcxx/test/libcxx/thread/semaphore.availability.fail.cpp b/libcxx/test/libcxx/thread/semaphore.availability.fail.cpp new file mode 100644 index 0000000..8776fb8 --- /dev/null +++ b/libcxx/test/libcxx/thread/semaphore.availability.fail.cpp @@ -0,0 +1,52 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 +// REQUIRES: verify-support +// REQUIRES: with_system_cxx_lib=macosx +// REQUIRES: availability=macosx10.7 || availability=macosx10.8 || availability=macosx10.9 || availability=macosx10.10 || availability=macosx10.11 || availability=macosx10.12 || availability=macosx10.13 || availability=macosx10.14 || availability=macosx10.15 + +// Test the availability markup on std::counting_semaphore and std::binary_semaphore. + +#include +#include + + +int main(int, char**) +{ + { + // Tests for std::counting_semaphore with non-default template argument + std::counting_semaphore<20> sem(10); + sem.release(); // expected-error {{is unavailable}} + sem.release(5); // expected-error {{is unavailable}} + sem.acquire(); // expected-error {{is unavailable}} + sem.try_acquire_for(std::chrono::milliseconds{3}); // expected-error 1-2 {{is unavailable}} + sem.try_acquire(); // expected-error {{is unavailable}} + sem.try_acquire_until(std::chrono::steady_clock::now()); // expected-error 1-2 {{is unavailable}} + } + { + // Tests for std::counting_semaphore with default template argument + std::counting_semaphore<> sem(10); + sem.release(); // expected-error {{is unavailable}} + sem.release(5); // expected-error {{is unavailable}} + sem.acquire(); // expected-error {{is unavailable}} + sem.try_acquire_for(std::chrono::milliseconds{3}); // expected-error 1-2 {{is unavailable}} + sem.try_acquire(); // expected-error {{is unavailable}} + sem.try_acquire_until(std::chrono::steady_clock::now()); // expected-error 1-2 {{is unavailable}} + } + { + // Tests for std::binary_semaphore + std::binary_semaphore sem(10); + sem.release(); // expected-error {{is unavailable}} + sem.release(5); // expected-error {{is unavailable}} + sem.acquire(); // expected-error {{is unavailable}} + sem.try_acquire_for(std::chrono::milliseconds{3}); // expected-error 1-2 {{is unavailable}} + sem.try_acquire(); // expected-error {{is unavailable}} + sem.try_acquire_until(std::chrono::steady_clock::now()); // expected-error 1-2 {{is unavailable}} + } +} -- 2.7.4