91 lines · cpp
1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7 8// UNSUPPORTED: c++03, c++11, c++14, c++179// UNSUPPORTED: no-threads10// XFAIL: !has-64-bit-atomics11// XFAIL: !has-1024-bit-atomics12 13// MSVC warning C4310: cast truncates constant value14// ADDITIONAL_COMPILE_FLAGS(cl-style-warnings): /wd431015 16// void wait(T, memory_order = memory_order::seq_cst) const noexcept;17 18#include <atomic>19#include <cassert>20#include <type_traits>21 22#include "atomic_helpers.h"23#include "make_test_thread.h"24#include "test_helper.h"25#include "test_macros.h"26 27template <typename T>28struct TestWait {29 void operator()() const {30 {31 T x(T(1));32 std::atomic_ref<T> const a(x);33 34 assert(a.load() == T(1));35 a.wait(T(0));36 std::thread t1 = support::make_test_thread([&]() {37 a.store(T(3));38 a.notify_one();39 });40 a.wait(T(1));41 assert(a.load() == T(3));42 t1.join();43 ASSERT_NOEXCEPT(a.wait(T(0)));44 45 assert(a.load() == T(3));46 a.wait(T(0), std::memory_order_seq_cst);47 std::thread t2 = support::make_test_thread([&]() {48 a.store(T(5));49 a.notify_one();50 });51 a.wait(T(3), std::memory_order_seq_cst);52 assert(a.load() == T(5));53 t2.join();54 ASSERT_NOEXCEPT(a.wait(T(0), std::memory_order_seq_cst));55 }56 57 // memory_order::acquire58 {59 auto store = [](std::atomic_ref<T> const& x, T, T new_val) { x.store(new_val, std::memory_order::release); };60 auto load = [](std::atomic_ref<T> const& x) {61 auto result = x.load(std::memory_order::relaxed);62 x.wait(T(255), std::memory_order::acquire);63 return result;64 };65 test_acquire_release<T>(store, load);66 }67 68 // memory_order::seq_cst69 {70 auto store = [](std::atomic_ref<T> const& x, T, T new_val) { x.store(new_val); };71 auto load_no_arg = [](std::atomic_ref<T> const& x) {72 auto result = x.load(std::memory_order::relaxed);73 x.wait(T(255));74 return result;75 };76 auto load_with_order = [](std::atomic_ref<T> const& x) {77 auto result = x.load(std::memory_order::relaxed);78 x.wait(T(255), std::memory_order::seq_cst);79 return result;80 };81 test_seq_cst<T>(store, load_no_arg);82 test_seq_cst<T>(store, load_with_order);83 }84 }85};86 87int main(int, char**) {88 TestEachAtomicType<TestWait>()();89 return 0;90}91