1/* { dg-do link } */ 2/* { dg-require-effective-target sync_int_long } */ 3/* { dg-final { simulate-thread } } */ 4 5 6#include <stdio.h> 7#include "simulate-thread.h" 8 9/* Test all the __sync routines for proper atomicity on 4 byte values. */ 10 11unsigned int zero = 0; 12unsigned int max = ~0; 13 14unsigned int changing_value = 0; 15unsigned int value = 0; 16unsigned int ret; 17 18void test_abort() 19{ 20 static int reported = 0; 21 if (!reported) 22 { 23 printf ("FAIL: improper execution of __sync builtin.\n"); 24 reported = 1; 25 } 26} 27 28void simulate_thread_other_threads () 29{ 30} 31 32int simulate_thread_step_verify () 33{ 34 if (value != zero && value != max) 35 { 36 printf ("FAIL: invalid intermediate result for value.\n"); 37 return 1; 38 } 39 return 0; 40} 41 42int simulate_thread_final_verify () 43{ 44 if (value != 0) 45 { 46 printf ("FAIL: invalid final result for value.\n"); 47 return 1; 48 } 49 return 0; 50} 51 52/* All values written to 'value' alternate between 'zero' and 53 'max'. Any other value detected by simulate_thread_step_verify() 54 between instructions would indicate that the value was only 55 partially written, and would thus fail this atomicity test. 56 57 This function tests each different __atomic routine once, with 58 the exception of the load instruction which requires special 59 testing. */ 60__attribute__((noinline)) 61void simulate_thread_main() 62{ 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 114main () 115{ 116 simulate_thread_main (); 117 simulate_thread_done (); 118 return 0; 119} 120