1 // { dg-do compile { target i?86-*-* x86_64-*-* } }
2 // { dg-options "-O2 -g0 -fno-exceptions -fno-asynchronous-unwind-tables" }
3 // { dg-additional-options "-march=i486" { target ia32 } }
4 // { dg-require-effective-target c++11 }
5 // { dg-skip-if "scans fail with LTO" { lto } { "-flto" } }
6 // { dg-final { scan-assembler-times "xacquire\|\.byte\[^\n\r]*0xf2" 14 } }
7 // { dg-final { scan-assembler-times "xrelease\|\.byte\[^\n\r]*0xf3" 14 } }
9 // Copyright (C) 2008-2020 Free Software Foundation, Inc.
11 // This file is part of the GNU ISO C++ Library. This library is free
12 // software; you can redistribute it and/or modify it under the
13 // terms of the GNU General Public License as published by the
14 // Free Software Foundation; either version 3, or (at your option)
17 // This library is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 // GNU General Public License for more details.
22 // You should have received a copy of the GNU General Public License along
23 // with this library; see the file COPYING3. If not see
24 // <http://www.gnu.org/licenses/>.
28 const auto ACQ
= std::memory_order_acquire
| std::__memory_order_hle_acquire
;
29 const auto REL
= std::memory_order_release
| std::__memory_order_hle_release
;
35 atomic_flag af
= ATOMIC_FLAG_INIT
;
37 if (!af
.test_and_set(ACQ
))
40 atomic_uint au
= ATOMIC_VAR_INIT(0);
42 if (au
.exchange(1, ACQ
))
45 if (au
.exchange(1, ACQ
))
50 if (au
.compare_exchange_weak(zero
, 1, ACQ
, memory_order_consume
))
51 au
.compare_exchange_weak(one
, 0, REL
, memory_order_consume
);
55 if (au
.compare_exchange_strong(zero
, 1, ACQ
, memory_order_consume
))
56 au
.compare_exchange_strong(one
, 0, REL
, memory_order_consume
);
58 if (!au
.fetch_add(1, ACQ
))
59 au
.fetch_add(-1, REL
);
61 if (!au
.fetch_sub(1, ACQ
))
62 au
.fetch_sub(-1, REL
);
64 #if 0 /* broken in underlying target */
65 if (!au
.fetch_and(1, ACQ
))
66 au
.fetch_and(-1, REL
);
68 if (!au
.fetch_or(1, ACQ
))
71 if (!au
.fetch_xor(1, ACQ
))
72 au
.fetch_xor(-1, REL
);
74 if (!au
.fetch_nand(1, ACQ
))
75 au
.fetch_nand(-1, REL
);
78 volatile atomic_flag vaf
= ATOMIC_FLAG_INIT
;
80 if (!vaf
.test_and_set(ACQ
))
83 volatile atomic_uint vau
= ATOMIC_VAR_INIT(0);
85 if (!vau
.exchange(1, ACQ
))
88 if (!vau
.exchange(1, ACQ
))
93 if (vau
.compare_exchange_weak(zero
, 1, ACQ
, memory_order_consume
))
94 vau
.compare_exchange_weak(one
, 0, REL
, memory_order_consume
);
98 if (vau
.compare_exchange_strong(zero
, 1, ACQ
, memory_order_consume
))
99 vau
.compare_exchange_strong(one
, 0, REL
, memory_order_consume
);
101 if (!vau
.fetch_add(1, ACQ
))
102 vau
.fetch_add(-1, REL
);
104 if (!vau
.fetch_sub(1, ACQ
))
105 vau
.fetch_sub(-1, REL
);
107 #if 0 /* broken in underlying target */
109 if (!vau
.fetch_and(1, ACQ
))
110 vau
.fetch_and(-1, REL
);
112 if (!vau
.fetch_or(1, ACQ
))
113 vau
.fetch_or(-1, REL
);
115 if (!vau
.fetch_xor(1, ACQ
))
116 vau
.fetch_xor(-1, REL
);
118 if (!vau
.fetch_nand(1, ACQ
))
119 vau
.fetch_nand(-1, REL
);