annotate gcc/testsuite/gcc.dg/simulate-thread/atomic-load-longlong.c @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 04ced10e8804
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* { dg-do link } */
kono
parents:
diff changeset
2 /* { dg-require-effective-target sync_long_long_runtime } */
kono
parents:
diff changeset
3 /* { dg-options "" } */
kono
parents:
diff changeset
4 /* { dg-options "-march=pentium" { target { { i?86-*-* x86_64-*-* } && ia32 } } } */
kono
parents:
diff changeset
5 /* { dg-final { simulate-thread } } */
kono
parents:
diff changeset
6
kono
parents:
diff changeset
7
kono
parents:
diff changeset
8 #include <stdio.h>
kono
parents:
diff changeset
9 #include "simulate-thread.h"
kono
parents:
diff changeset
10
kono
parents:
diff changeset
11
kono
parents:
diff changeset
12 /* Testing load for atomicity is a little trickier.
kono
parents:
diff changeset
13
kono
parents:
diff changeset
14 Set up the atomic value so that it changes value after every instruction
kono
parents:
diff changeset
15 is executed.
kono
parents:
diff changeset
16
kono
parents:
diff changeset
17 Simply alternating between 2 values wouldn't be sufficient since a load of
kono
parents:
diff changeset
18 one part, followed by the load of the second part 2 instructions later would
kono
parents:
diff changeset
19 appear to be valid.
kono
parents:
diff changeset
20
kono
parents:
diff changeset
21 set up a table of 16 values which change a bit in every byte of the value
kono
parents:
diff changeset
22 each time, this will give us a 16 instruction cycle before repetition
kono
parents:
diff changeset
23 kicks in, which should be sufficient to detect any issues. Just to be sure,
kono
parents:
diff changeset
24 we also change the table cycle size during execution.
kono
parents:
diff changeset
25
kono
parents:
diff changeset
26 The end result is that all loads should always get one of the values from
kono
parents:
diff changeset
27 the table. Any other pattern means the load failed. */
kono
parents:
diff changeset
28
kono
parents:
diff changeset
29 unsigned long long ret;
kono
parents:
diff changeset
30 unsigned long long value = 0;
kono
parents:
diff changeset
31 unsigned long long result = 0;
kono
parents:
diff changeset
32 unsigned long long table[16] = {
kono
parents:
diff changeset
33 0x0000000000000000,
kono
parents:
diff changeset
34 0x1111111111111111,
kono
parents:
diff changeset
35 0x2222222222222222,
kono
parents:
diff changeset
36 0x3333333333333333,
kono
parents:
diff changeset
37 0x4444444444444444,
kono
parents:
diff changeset
38 0x5555555555555555,
kono
parents:
diff changeset
39 0x6666666666666666,
kono
parents:
diff changeset
40 0x7777777777777777,
kono
parents:
diff changeset
41 0x8888888888888888,
kono
parents:
diff changeset
42 0x9999999999999999,
kono
parents:
diff changeset
43 0xAAAAAAAAAAAAAAAA,
kono
parents:
diff changeset
44 0xBBBBBBBBBBBBBBBB,
kono
parents:
diff changeset
45 0xCCCCCCCCCCCCCCCC,
kono
parents:
diff changeset
46 0xDDDDDDDDDDDDDDDD,
kono
parents:
diff changeset
47 0xEEEEEEEEEEEEEEEE,
kono
parents:
diff changeset
48 0xFFFFFFFFFFFFFFFF
kono
parents:
diff changeset
49 };
kono
parents:
diff changeset
50
kono
parents:
diff changeset
51 int table_cycle_size = 16;
kono
parents:
diff changeset
52
kono
parents:
diff changeset
53 /* Return 0 if 'result' is a valid value to have loaded. */
kono
parents:
diff changeset
54 int verify_result ()
kono
parents:
diff changeset
55 {
kono
parents:
diff changeset
56 int x;
kono
parents:
diff changeset
57 int found = 0;
kono
parents:
diff changeset
58
kono
parents:
diff changeset
59 /* Check entire table for valid values. */
kono
parents:
diff changeset
60 for (x = 0; x < 16 ; x++)
kono
parents:
diff changeset
61 if (result == table[x])
kono
parents:
diff changeset
62 {
kono
parents:
diff changeset
63 found = 1;
kono
parents:
diff changeset
64 break;
kono
parents:
diff changeset
65 }
kono
parents:
diff changeset
66
kono
parents:
diff changeset
67 if (!found)
kono
parents:
diff changeset
68 printf("FAIL: Invalid result returned from fetch\n");
kono
parents:
diff changeset
69
kono
parents:
diff changeset
70 return !found;
kono
parents:
diff changeset
71 }
kono
parents:
diff changeset
72
kono
parents:
diff changeset
73 /* Iterate VALUE through the different valid values. */
kono
parents:
diff changeset
74 void simulate_thread_other_threads ()
kono
parents:
diff changeset
75 {
kono
parents:
diff changeset
76 static int current = 0;
kono
parents:
diff changeset
77
kono
parents:
diff changeset
78 if (++current >= table_cycle_size)
kono
parents:
diff changeset
79 current = 0;
kono
parents:
diff changeset
80 value = table[current];
kono
parents:
diff changeset
81 }
kono
parents:
diff changeset
82
kono
parents:
diff changeset
83 int simulate_thread_step_verify ()
kono
parents:
diff changeset
84 {
kono
parents:
diff changeset
85 return verify_result ();
kono
parents:
diff changeset
86 }
kono
parents:
diff changeset
87
kono
parents:
diff changeset
88 int simulate_thread_final_verify ()
kono
parents:
diff changeset
89 {
kono
parents:
diff changeset
90 return verify_result ();
kono
parents:
diff changeset
91 }
kono
parents:
diff changeset
92
kono
parents:
diff changeset
93 __attribute__((noinline))
kono
parents:
diff changeset
94 void simulate_thread_main()
kono
parents:
diff changeset
95 {
kono
parents:
diff changeset
96 int x;
kono
parents:
diff changeset
97
kono
parents:
diff changeset
98 /* Execute loads with value changing at various cyclic values. */
kono
parents:
diff changeset
99 for (table_cycle_size = 16; table_cycle_size > 4 ; table_cycle_size--)
kono
parents:
diff changeset
100 {
kono
parents:
diff changeset
101 ret = __atomic_load_n (&value, __ATOMIC_SEQ_CST);
kono
parents:
diff changeset
102 /* In order to verify the returned value (which is not atomic), it needs
kono
parents:
diff changeset
103 to be atomically stored into another variable and check that. */
kono
parents:
diff changeset
104 __atomic_store_n (&result, ret, __ATOMIC_SEQ_CST);
kono
parents:
diff changeset
105
kono
parents:
diff changeset
106 /* Execute the fetch/store a couple of times just to ensure the cycles
kono
parents:
diff changeset
107 have a chance to be interesting. */
kono
parents:
diff changeset
108 ret = __atomic_load_n (&value, __ATOMIC_SEQ_CST);
kono
parents:
diff changeset
109 __atomic_store_n (&result, ret, __ATOMIC_SEQ_CST);
kono
parents:
diff changeset
110 }
kono
parents:
diff changeset
111 }
kono
parents:
diff changeset
112
kono
parents:
diff changeset
113 int
kono
parents:
diff changeset
114 main()
kono
parents:
diff changeset
115 {
kono
parents:
diff changeset
116 simulate_thread_main ();
kono
parents:
diff changeset
117 simulate_thread_done ();
kono
parents:
diff changeset
118 return 0;
kono
parents:
diff changeset
119 }