aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.dg/simulate-thread/atomic-other-short.c
diff options
context:
space:
mode:
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.c117
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;
+}