111
|
1 /* { dg-do link } */
|
|
2 /* { dg-require-effective-target sync_long_long_runtime } */
|
|
3 /* { dg-options "" } */
|
|
4 /* { dg-options "-march=pentium" { target { { i?86-*-* x86_64-*-* } && ia32 } } } */
|
|
5 /* { dg-final { simulate-thread } } */
|
|
6
|
|
7
|
|
8 #include <stdio.h>
|
|
9 #include "simulate-thread.h"
|
|
10
|
|
11 /* Test all the __sync routines for proper atomicity on 8 byte values. */
|
|
12
|
|
13 unsigned long long zero = 0;
|
|
14 unsigned long long max = ~0;
|
|
15
|
|
16 unsigned long long changing_value = 0;
|
|
17 unsigned long long value = 0;
|
|
18 unsigned long long ret;
|
|
19
|
|
20 void test_abort()
|
|
21 {
|
|
22 static int reported = 0;
|
|
23 if (!reported)
|
|
24 {
|
|
25 printf ("FAIL: improper execution of __sync builtin.\n");
|
|
26 reported = 1;
|
|
27 }
|
|
28 }
|
|
29
|
|
30 void simulate_thread_other_threads ()
|
|
31 {
|
|
32 }
|
|
33
|
|
34 int simulate_thread_step_verify ()
|
|
35 {
|
|
36 if (value != zero && value != max)
|
|
37 {
|
|
38 printf ("FAIL: invalid intermediate result for value.\n");
|
|
39 return 1;
|
|
40 }
|
|
41 return 0;
|
|
42 }
|
|
43
|
|
44 int simulate_thread_final_verify ()
|
|
45 {
|
|
46 if (value != 0)
|
|
47 {
|
|
48 printf ("FAIL: invalid final result for value.\n");
|
|
49 return 1;
|
|
50 }
|
|
51 return 0;
|
|
52 }
|
|
53
|
|
54 /* All values written to 'value' alternate between 'zero' and 'max'. Any other
|
|
55 value detected by simulate_thread_step_verify() between instructions would indicate
|
|
56 that the value was only partially written, and would thus fail this
|
|
57 atomicity test.
|
|
58
|
|
59 This function tests each different __atomic routine once, with the
|
|
60 exception of the load instruction which requires special testing. */
|
|
61 __attribute__((noinline))
|
|
62 void simulate_thread_main()
|
|
63 {
|
|
64 ret = __atomic_exchange_n (&value, max, __ATOMIC_SEQ_CST);
|
|
65 if (ret != zero || value != max)
|
|
66 test_abort();
|
|
67
|
|
68 __atomic_store_n (&value, zero, __ATOMIC_SEQ_CST);
|
|
69 if (value != zero)
|
|
70 test_abort();
|
|
71
|
|
72 ret = __atomic_fetch_add (&value, max, __ATOMIC_SEQ_CST);
|
|
73 if (value != max || ret != zero)
|
|
74 test_abort ();
|
|
75
|
|
76 ret = __atomic_fetch_sub (&value, max, __ATOMIC_SEQ_CST);
|
|
77 if (value != zero || ret != max)
|
|
78 test_abort ();
|
|
79
|
|
80 ret = __atomic_fetch_or (&value, max, __ATOMIC_SEQ_CST);
|
|
81 if (value != max || ret != zero)
|
|
82 test_abort ();
|
|
83
|
|
84 ret = __atomic_fetch_and (&value, max, __ATOMIC_SEQ_CST);
|
|
85 if (value != max || ret != max)
|
|
86 test_abort ();
|
|
87
|
|
88 ret = __atomic_fetch_xor (&value, max, __ATOMIC_SEQ_CST);
|
|
89 if (value != zero || ret != max)
|
|
90 test_abort ();
|
|
91
|
|
92 ret = __atomic_add_fetch (&value, max, __ATOMIC_SEQ_CST);
|
|
93 if (value != max || ret != max)
|
|
94 test_abort ();
|
|
95
|
|
96 ret = __atomic_sub_fetch (&value, max, __ATOMIC_SEQ_CST);
|
|
97 if (value != zero || ret != zero)
|
|
98 test_abort ();
|
|
99
|
|
100 ret = __atomic_or_fetch (&value, max, __ATOMIC_SEQ_CST);
|
|
101 if (value != max || ret != max)
|
|
102 test_abort ();
|
|
103
|
|
104 ret = __atomic_and_fetch (&value, max, __ATOMIC_SEQ_CST);
|
|
105 if (value != max || ret != max)
|
|
106 test_abort ();
|
|
107
|
|
108 ret = __atomic_xor_fetch (&value, max, __ATOMIC_SEQ_CST);
|
|
109 if (value != zero || ret != zero)
|
|
110 test_abort ();
|
|
111 }
|
|
112
|
|
113 int main ()
|
|
114 {
|
|
115 simulate_thread_main ();
|
|
116 simulate_thread_done ();
|
|
117 return 0;
|
|
118 }
|