summaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.dg/simulate-thread/atomic-other-longlong.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/testsuite/gcc.dg/simulate-thread/atomic-other-longlong.c')
-rw-r--r--gcc/testsuite/gcc.dg/simulate-thread/atomic-other-longlong.c117
1 files changed, 117 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.dg/simulate-thread/atomic-other-longlong.c b/gcc/testsuite/gcc.dg/simulate-thread/atomic-other-longlong.c
new file mode 100644
index 00000000000..ac4330bd8a4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/simulate-thread/atomic-other-longlong.c
@@ -0,0 +1,117 @@
+/* { dg-do link } */
+/* { dg-require-effective-target sync_long_long } */
+/* { dg-options "" } */
+/* { dg-final { simulate-thread } } */
+
+
+#include <stdio.h>
+#include "simulate-thread.h"
+
+/* Test all the __sync routines for proper atomicity on 8 byte values. */
+
+unsigned long long zero = 0;
+unsigned long long max = ~0;
+
+unsigned long long changing_value = 0;
+unsigned long long value = 0;
+unsigned long long 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;
+}