/* { dg-do link } */ /* { dg-require-effective-target sync_char_short } */ /* { dg-final { simulate-thread } } */ #include #include "simulate-thread.h" /* Test all the __sync routines for proper atomicity on 2 byte values. */ unsigned short zero = 0; unsigned short max = ~0; unsigned short changing_value = 0; unsigned short value = 0; unsigned short ret; void test_abort() { static int reported = 0; if (!reported) { printf ("FAIL: improper execution of __sync builtin.\n"); reported = 1; } } void simulate_thread_other_threads () { } int simulate_thread_step_verify () { if (value != zero && value != max) { printf ("FAIL: invalid intermediate result for value.\n"); return 1; } return 0; } int simulate_thread_final_verify () { if (value != 0) { printf ("FAIL: invalid final result for value.\n"); return 1; } return 0; } /* All values written to 'value' alternate between 'zero' and 'max'. Any other value detected by simulate_thread_step_verify() between instructions would indicate that the value was only partially written, and would thus fail this atomicity test. This function tests each different __atomic routine once, with the exception of the load instruction which requires special testing. */ __attribute__((noinline)) void simulate_thread_main() { ret = __atomic_exchange_n (&value, max, __ATOMIC_SEQ_CST); if (ret != zero || value != max) test_abort(); __atomic_store_n (&value, zero, __ATOMIC_SEQ_CST); if (value != zero) test_abort(); ret = __atomic_fetch_add (&value, max, __ATOMIC_SEQ_CST); if (value != max || ret != zero) test_abort (); ret = __atomic_fetch_sub (&value, max, __ATOMIC_SEQ_CST); if (value != zero || ret != max) test_abort (); ret = __atomic_fetch_or (&value, max, __ATOMIC_SEQ_CST); if (value != max || ret != zero) test_abort (); ret = __atomic_fetch_and (&value, max, __ATOMIC_SEQ_CST); if (value != max || ret != max) test_abort (); ret = __atomic_fetch_xor (&value, max, __ATOMIC_SEQ_CST); if (value != zero || ret != max) test_abort (); ret = __atomic_add_fetch (&value, max, __ATOMIC_SEQ_CST); if (value != max || ret != max) test_abort (); ret = __atomic_sub_fetch (&value, max, __ATOMIC_SEQ_CST); if (value != zero || ret != zero) test_abort (); ret = __atomic_or_fetch (&value, max, __ATOMIC_SEQ_CST); if (value != max || ret != max) test_abort (); ret = __atomic_and_fetch (&value, max, __ATOMIC_SEQ_CST); if (value != max || ret != max) test_abort (); ret = __atomic_xor_fetch (&value, max, __ATOMIC_SEQ_CST); if (value != zero || ret != zero) test_abort (); } int main () { simulate_thread_main (); simulate_thread_done (); return 0; }