Imported Upstream version 4.8.1
[platform/upstream/gcc48.git] / libstdc++-v3 / testsuite / 29_atomics / atomic_flag / test_and_set / explicit-hle.cc
1 // { dg-do compile { target i?86-*-* x86_64-*-* } }
2 // { dg-options "-std=gnu++0x -g0 -fno-exceptions -fno-asynchronous-unwind-tables" }
3 // { dg-options "-std=gnu++0x -g0 -fno-exceptions -fno-asynchronous-unwind-tables -march=i486" { target ia32 } }
4 // { dg-final { scan-assembler-times "xacquire\|\.byte\[^\n\r]*0xf2" 14 } }
5 // { dg-final { scan-assembler-times "xrelease\|\.byte\[^\n\r]*0xf3" 14 } }
6
7 // Copyright (C) 2008-2013 Free Software Foundation, Inc.
8 //
9 // This file is part of the GNU ISO C++ Library.  This library is free
10 // software; you can redistribute it and/or modify it under the
11 // terms of the GNU General Public License as published by the
12 // Free Software Foundation; either version 3, or (at your option)
13 // any later version.
14
15 // This library is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 // GNU General Public License for more details.
19
20 // You should have received a copy of the GNU General Public License along
21 // with this library; see the file COPYING3.  If not see
22 // <http://www.gnu.org/licenses/>.
23
24 #include <atomic>
25
26 #define ACQ memory_order_acquire | __memory_order_hle_acquire
27 #define REL memory_order_release | __memory_order_hle_release
28
29 int main()
30 {
31   unsigned zero, one;
32   using namespace std;
33   atomic_flag af = ATOMIC_FLAG_INIT;
34
35   if (!af.test_and_set(ACQ))
36     af.clear(REL);
37
38   atomic_uint au = ATOMIC_VAR_INIT(0);
39
40   if (au.exchange(1, ACQ))
41     au.store(0, REL);
42
43   if (au.exchange(1, ACQ))
44     au.exchange(0, REL);
45
46   zero = 0;
47   one = 1;
48   if (au.compare_exchange_weak(zero, 1, ACQ, memory_order_consume))
49     au.compare_exchange_weak(one, 0, REL, memory_order_consume);
50
51   zero = 0;
52   one = 1;
53   if (au.compare_exchange_strong(zero, 1, ACQ, memory_order_consume))
54     au.compare_exchange_strong(one, 0, REL, memory_order_consume);
55
56   if (!au.fetch_add(1, ACQ))
57     au.fetch_add(-1, REL);
58
59   if (!au.fetch_sub(1, ACQ))
60     au.fetch_sub(-1, REL);
61
62 #if 0 /* broken in underlying target */
63   if (!au.fetch_and(1, ACQ))
64     au.fetch_and(-1, REL);
65
66   if (!au.fetch_or(1, ACQ))
67     au.fetch_or(-1, REL);
68
69   if (!au.fetch_xor(1, ACQ))
70     au.fetch_xor(-1, REL);
71
72   if (!au.fetch_nand(1, ACQ))
73     au.fetch_nand(-1, REL);
74 #endif
75
76   volatile atomic_flag vaf = ATOMIC_FLAG_INIT;
77
78   if (!vaf.test_and_set(ACQ))
79     vaf.clear(REL);
80
81   volatile atomic_uint vau = ATOMIC_VAR_INIT(0);
82
83   if (!vau.exchange(1, ACQ))
84     vau.store(0, REL);
85
86   if (!vau.exchange(1, ACQ))
87     vau.exchange(0, REL);
88
89   zero = 0;
90   one = 1;
91   if (vau.compare_exchange_weak(zero, 1, ACQ, memory_order_consume))
92     vau.compare_exchange_weak(one, 0, REL, memory_order_consume);
93
94   zero = 0;
95   one = 1;
96   if (vau.compare_exchange_strong(zero, 1, ACQ, memory_order_consume))
97     vau.compare_exchange_strong(one, 0, REL, memory_order_consume);
98
99   if (!vau.fetch_add(1, ACQ))
100     vau.fetch_add(-1, REL);
101
102   if (!vau.fetch_sub(1, ACQ))
103     vau.fetch_sub(-1, REL);
104
105 #if 0 /* broken in underlying target */
106
107   if (!vau.fetch_and(1, ACQ))
108     vau.fetch_and(-1, REL);
109
110   if (!vau.fetch_or(1, ACQ))
111     vau.fetch_or(-1, REL);
112
113   if (!vau.fetch_xor(1, ACQ))
114     vau.fetch_xor(-1, REL);
115
116   if (!vau.fetch_nand(1, ACQ))
117     vau.fetch_nand(-1, REL);
118 #endif
119
120   return 0;
121 }