diff options
Diffstat (limited to 'gcc/testsuite/gcc.dg/simulate-thread/atomic-other-short.c')
-rw-r--r-- | gcc/testsuite/gcc.dg/simulate-thread/atomic-other-short.c | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.dg/simulate-thread/atomic-other-short.c b/gcc/testsuite/gcc.dg/simulate-thread/atomic-other-short.c new file mode 100644 index 00000000000..d823e02fb47 --- /dev/null +++ b/gcc/testsuite/gcc.dg/simulate-thread/atomic-other-short.c @@ -0,0 +1,117 @@ +/* { dg-do link } */ +/* { dg-require-effective-target sync_char_short } */ +/* { dg-final { simulate-thread } } */ + + +#include <stdio.h> +#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; +} |