1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // UNSUPPORTED: libcpp-has-no-threads
10 
11 // <atomic>
12 
13 // struct atomic_flag
14 
15 // bool atomic_flag_test_explicit(volatile atomic_flag*, memory_order);
16 // bool atomic_flag_test_explicit(atomic_flag*, memory_order);
17 
18 #include <atomic>
19 #include <cassert>
20 
21 #include "test_macros.h"
22 
main(int,char **)23 int main(int, char**)
24 {
25     {
26         std::atomic_flag f;
27         f.clear();
28         assert(atomic_flag_test_explicit(&f, std::memory_order_relaxed) == 0);
29         assert(f.test_and_set() == 0);
30         assert(atomic_flag_test_explicit(&f, std::memory_order_relaxed) == 1);
31     }
32     {
33         std::atomic_flag f;
34         f.clear();
35         assert(atomic_flag_test_explicit(&f, std::memory_order_consume) == 0);
36         assert(f.test_and_set() == 0);
37         assert(atomic_flag_test_explicit(&f, std::memory_order_consume) == 1);
38     }
39     {
40         std::atomic_flag f;
41         f.clear();
42         assert(atomic_flag_test_explicit(&f, std::memory_order_acquire) == 0);
43         assert(f.test_and_set() == 0);
44         assert(atomic_flag_test_explicit(&f, std::memory_order_acquire) == 1);
45     }
46 #ifdef _LIBCPP_VERSION // Don't violate precondition [atomics.flag]/6
47     {
48         std::atomic_flag f;
49         f.clear();
50         assert(atomic_flag_test_explicit(&f, std::memory_order_release) == 0);
51         assert(f.test_and_set() == 0);
52         assert(atomic_flag_test_explicit(&f, std::memory_order_release) == 1);
53     }
54     {
55         std::atomic_flag f;
56         f.clear();
57         assert(atomic_flag_test_explicit(&f, std::memory_order_acq_rel) == 0);
58         assert(f.test_and_set() == 0);
59         assert(atomic_flag_test_explicit(&f, std::memory_order_acq_rel) == 1);
60     }
61 #endif // _LIBCPP_VERSION
62     {
63         std::atomic_flag f;
64         f.clear();
65         assert(atomic_flag_test_explicit(&f, std::memory_order_seq_cst) == 0);
66         assert(f.test_and_set() == 0);
67         assert(atomic_flag_test_explicit(&f, std::memory_order_seq_cst) == 1);
68     }
69     {
70         volatile std::atomic_flag f;
71         f.clear();
72         assert(atomic_flag_test_explicit(&f, std::memory_order_relaxed) == 0);
73         assert(f.test_and_set() == 0);
74         assert(atomic_flag_test_explicit(&f, std::memory_order_relaxed) == 1);
75     }
76     {
77         volatile std::atomic_flag f;
78         f.clear();
79         assert(atomic_flag_test_explicit(&f, std::memory_order_consume) == 0);
80         assert(f.test_and_set() == 0);
81         assert(atomic_flag_test_explicit(&f, std::memory_order_consume) == 1);
82     }
83     {
84         volatile std::atomic_flag f;
85         f.clear();
86         assert(atomic_flag_test_explicit(&f, std::memory_order_acquire) == 0);
87         assert(f.test_and_set() == 0);
88         assert(atomic_flag_test_explicit(&f, std::memory_order_acquire) == 1);
89     }
90 #ifdef _LIBCPP_VERSION // Don't violate precondition [atomics.flag]/6
91     {
92         volatile std::atomic_flag f;
93         f.clear();
94         assert(atomic_flag_test_explicit(&f, std::memory_order_release) == 0);
95         assert(f.test_and_set() == 0);
96         assert(atomic_flag_test_explicit(&f, std::memory_order_release) == 1);
97     }
98     {
99         volatile std::atomic_flag f;
100         f.clear();
101         assert(atomic_flag_test_explicit(&f, std::memory_order_acq_rel) == 0);
102         assert(f.test_and_set() == 0);
103         assert(atomic_flag_test_explicit(&f, std::memory_order_acq_rel) == 1);
104     }
105 #endif // _LIBCPP_VERSION
106     {
107         volatile std::atomic_flag f;
108         f.clear();
109         assert(atomic_flag_test_explicit(&f, std::memory_order_seq_cst) == 0);
110         assert(f.test_and_set() == 0);
111         assert(atomic_flag_test_explicit(&f, std::memory_order_seq_cst) == 1);
112     }
113 
114   return 0;
115 }
116