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 13unsigned long long zero = 0; 14unsigned long long max = ~0; 15 16unsigned long long changing_value = 0; 17unsigned long long value = 0; 18unsigned long long ret; 19 20void 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 30void simulate_thread_other_threads () 31{ 32} 33 34int 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 44int 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)) 62void 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 113int main () 114{ 115 simulate_thread_main (); 116 simulate_thread_done (); 117 return 0; 118} 119