summaryrefslogtreecommitdiffstats
path: root/testsuites/sptests/spatomic07/tasks.c
diff options
context:
space:
mode:
Diffstat (limited to 'testsuites/sptests/spatomic07/tasks.c')
-rw-r--r--testsuites/sptests/spatomic07/tasks.c124
1 files changed, 124 insertions, 0 deletions
diff --git a/testsuites/sptests/spatomic07/tasks.c b/testsuites/sptests/spatomic07/tasks.c
new file mode 100644
index 0000000000..ff925d0118
--- /dev/null
+++ b/testsuites/sptests/spatomic07/tasks.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2012 Deng Hengyi.
+ *
+ * This test case is to test atomic compare and exchange operation.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "system.h"
+
+#include <stdlib.h>
+#include <rtems/rtems/atomic.h>
+
+#define TEST_REPEAT 200000
+
+#define ATOMIC_CAS_NO_BARRIER(NAME, TYPE, task_id, mem_bar) \
+{ \
+ Atomic_##TYPE a = 0, b = 0; \
+ unsigned int i; \
+ int r; \
+ for (i = 0; i < TEST_REPEAT; i++){ \
+ a = rand() % (Atomic_##TYPE)-1; \
+ b = a; \
+ r = _Atomic_Compare_exchange_##NAME(&b, a + 1, a - 1, mem_bar); \
+ if(r != 0){ \
+ printf("\ntask%d: _Atomic_Compare_exchange_" #NAME ": FAILED\n", (unsigned int)task_id); \
+ rtems_test_exit( 0 ); \
+ } \
+ b = a; \
+ r = _Atomic_Compare_exchange_##NAME(&b, a, a - 1, mem_bar); \
+ if((r == 0) ||((r != 0) && ((a - 1) != b))){ \
+ printf("\ntask%d: _Atomic_Compare_exchange_" #NAME ": FAILED\n", (unsigned int)task_id); \
+ rtems_test_exit( 0 ); \
+ } \
+ b = a; \
+ r = _Atomic_Compare_exchange_##NAME(&b, a + 1, a, mem_bar); \
+ if(r != 0){ \
+ printf("\ntask%d: _Atomic_Compare_exchange_" #NAME ": FAILED\n", (unsigned int)task_id); \
+ rtems_test_exit( 0 ); \
+ } \
+ } \
+ printf("\ntask%d: _Atomic_Compare_exchange_" #NAME ": SUCCESS\n", (unsigned int)task_id); \
+}
+
+rtems_task Test_task(
+ rtems_task_argument argument
+ )
+{
+ char name[5];
+ char *p;
+ rtems_status_code status;
+
+ /* Get the task name */
+ p = rtems_object_get_name( RTEMS_SELF, 5, name );
+ rtems_test_assert( p != NULL );
+
+ /* Print that the task is up and running. */
+ /* test relaxed barrier */
+ ATOMIC_CAS_NO_BARRIER(int, Int, argument, ATOMIC_RELAXED_BARRIER);
+
+ ATOMIC_CAS_NO_BARRIER(long, Long, argument, ATOMIC_RELAXED_BARRIER);
+
+ ATOMIC_CAS_NO_BARRIER(ptr, Pointer, argument, ATOMIC_RELAXED_BARRIER);
+
+ ATOMIC_CAS_NO_BARRIER(32, Int32, argument, ATOMIC_RELAXED_BARRIER);
+
+ /* test acquire barrier */
+ ATOMIC_CAS_NO_BARRIER(int, Int, argument, ATOMIC_ACQUIRE_BARRIER);
+
+ ATOMIC_CAS_NO_BARRIER(long, Long, argument, ATOMIC_ACQUIRE_BARRIER);
+
+ ATOMIC_CAS_NO_BARRIER(ptr, Pointer, argument, ATOMIC_ACQUIRE_BARRIER);
+
+ ATOMIC_CAS_NO_BARRIER(32, Int32, argument, ATOMIC_ACQUIRE_BARRIER);
+
+ /* test release barrier */
+ ATOMIC_CAS_NO_BARRIER(int, Int, argument, ATOMIC_RELEASE_BARRIER);
+
+ ATOMIC_CAS_NO_BARRIER(long, Long, argument, ATOMIC_RELEASE_BARRIER);
+
+ ATOMIC_CAS_NO_BARRIER(ptr, Pointer, argument, ATOMIC_RELEASE_BARRIER);
+
+ ATOMIC_CAS_NO_BARRIER(32, Int32, argument, ATOMIC_RELEASE_BARRIER);
+
+ /* Set the flag that the task is up and running */
+ TaskRan[argument] = true;
+
+ status = rtems_task_delete( RTEMS_SELF );
+ directive_failed( status, "delete" );
+}
+
+rtems_task Wait_task(
+ rtems_task_argument argument
+ )
+{
+ char name[5];
+ char *p;
+ bool allDone;
+ int i;
+
+ /* Get the task name */
+ p = rtems_object_get_name( RTEMS_SELF, 5, name );
+ rtems_test_assert( p != NULL );
+
+ /* Wait on the all tasks to run */
+ while (1) {
+ allDone = true;
+ for ( i=0; i<TASK_NUMS ; i++ ) {
+ if (TaskRan[i] == false)
+ allDone = false;
+ }
+ if (allDone) {
+ puts( "\n\n*** END OF TEST spatomic07 ***\n" );
+ rtems_test_exit( 0 );
+ }
+ }
+}