1/* { dg-do link } */ 2/* { dg-require-effective-target sync_char_short } */ 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 2 byte values. */ 10 11unsigned short zero = 0; 12unsigned short max = ~0; 13 14unsigned short changing_value = 0; 15unsigned short value = 0; 16unsigned short 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 ret = __atomic_exchange_n (&value, max, __ATOMIC_SEQ_CST); 64 if (ret != zero || value != max) 65 test_abort(); 66 67 __atomic_store_n (&value, zero, __ATOMIC_SEQ_CST); 68 if (value != zero) 69 test_abort(); 70 71 ret = __atomic_fetch_add (&value, max, __ATOMIC_SEQ_CST); 72 if (value != max || ret != zero) 73 test_abort (); 74 75 ret = __atomic_fetch_sub (&value, max, __ATOMIC_SEQ_CST); 76 if (value != zero || ret != max) 77 test_abort (); 78 79 ret = __atomic_fetch_or (&value, max, __ATOMIC_SEQ_CST); 80 if (value != max || ret != zero) 81 test_abort (); 82 83 ret = __atomic_fetch_and (&value, max, __ATOMIC_SEQ_CST); 84 if (value != max || ret != max) 85 test_abort (); 86 87 ret = __atomic_fetch_xor (&value, max, __ATOMIC_SEQ_CST); 88 if (value != zero || ret != max) 89 test_abort (); 90 91 ret = __atomic_add_fetch (&value, max, __ATOMIC_SEQ_CST); 92 if (value != max || ret != max) 93 test_abort (); 94 95 ret = __atomic_sub_fetch (&value, max, __ATOMIC_SEQ_CST); 96 if (value != zero || ret != zero) 97 test_abort (); 98 99 ret = __atomic_or_fetch (&value, max, __ATOMIC_SEQ_CST); 100 if (value != max || ret != max) 101 test_abort (); 102 103 ret = __atomic_and_fetch (&value, max, __ATOMIC_SEQ_CST); 104 if (value != max || ret != max) 105 test_abort (); 106 107 ret = __atomic_xor_fetch (&value, max, __ATOMIC_SEQ_CST); 108 if (value != zero || ret != zero) 109 test_abort (); 110} 111 112int main () 113{ 114 simulate_thread_main (); 115 simulate_thread_done (); 116 return 0; 117} 118