Add rcu_read_ongoing() API to each urcu flavor
[urcu.git] / tests / test_urcu.c
index 870f133ab75f82b03f997cea1518f9e1979e4403..5059ddeac51648b5f901cdb5c3a1483aac7a1480 100644 (file)
 #include <unistd.h>
 #include <stdio.h>
 #include <assert.h>
-#include <sched.h>
 #include <errno.h>
 
 #include <urcu/arch.h>
+#include <urcu/tls-compat.h>
+#include "cpuset.h"
 
 #ifdef __linux__
 #include <syscall.h>
@@ -61,19 +62,15 @@ static inline pid_t gettid(void)
 #ifndef DYNAMIC_LINK_TEST
 #define _LGPL_SOURCE
 #else
-#define debug_yield_read()
+#define rcu_debug_yield_read()
 #endif
 #include <urcu.h>
 
-struct test_array {
-       int a;
-};
-
 static volatile int test_go, test_stop;
 
 static unsigned long wdelay;
 
-static struct test_array *test_rcu_pointer;
+static int *test_rcu_pointer;
 
 static unsigned long duration;
 
@@ -83,9 +80,9 @@ static unsigned long rduration;
 /* write-side C.S. duration, in loops */
 static unsigned long wduration;
 
-static inline void loop_sleep(unsigned long l)
+static inline void loop_sleep(unsigned long loops)
 {
-       while(l-- != 0)
+       while (loops-- != 0)
                caa_cpu_relax();
 }
 
@@ -103,17 +100,12 @@ static int use_affinity = 0;
 
 pthread_mutex_t affinity_mutex = PTHREAD_MUTEX_INITIALIZER;
 
-#ifndef HAVE_CPU_SET_T
-typedef unsigned long cpu_set_t;
-# define CPU_ZERO(cpuset) do { *(cpuset) = 0; } while(0)
-# define CPU_SET(cpu, cpuset) do { *(cpuset) |= (1UL << (cpu)); } while(0)
-#endif
-
 static void set_affinity(void)
 {
+#if HAVE_SCHED_SETAFFINITY
        cpu_set_t mask;
-       int cpu;
-       int ret;
+       int cpu, ret;
+#endif /* HAVE_SCHED_SETAFFINITY */
 
        if (!use_affinity)
                return;
@@ -154,8 +146,8 @@ static int test_duration_read(void)
        return !test_stop;
 }
 
-static unsigned long long __thread nr_writes;
-static unsigned long long __thread nr_reads;
+static DEFINE_URCU_TLS(unsigned long long, nr_writes);
+static DEFINE_URCU_TLS(unsigned long long, nr_reads);
 
 static unsigned int nr_readers;
 static unsigned int nr_writers;
@@ -183,50 +175,19 @@ void rcu_copy_mutex_unlock(void)
        }
 }
 
-/*
- * malloc/free are reusing memory areas too quickly, which does not let us
- * test races appropriately. Use a large circular array for allocations.
- * ARRAY_SIZE is larger than nr_writers, and we keep the mutex across
- * both alloc and free, which insures we never run over our tail.
- */
-#define ARRAY_SIZE (1048576 * nr_writers)
-#define ARRAY_POISON 0xDEADBEEF
-static int array_index;
-static struct test_array *test_array;
-
-static struct test_array *test_array_alloc(void)
-{
-       struct test_array *ret;
-       int index;
-
-       index = array_index % ARRAY_SIZE;
-       assert(test_array[index].a == ARRAY_POISON ||
-               test_array[index].a == 0);
-       ret = &test_array[index];
-       array_index++;
-       if (array_index == ARRAY_SIZE)
-               array_index = 0;
-       return ret;
-}
-
-static void test_array_free(struct test_array *ptr)
-{
-       if (!ptr)
-               return;
-       ptr->a = ARRAY_POISON;
-}
-
 void *thr_reader(void *_count)
 {
        unsigned long long *count = _count;
-       struct test_array *local_ptr;
+       int *local_ptr;
 
        printf_verbose("thread_begin %s, thread id : %lx, tid %lu\n",
-                       "reader", pthread_self(), (unsigned long)gettid());
+                       "reader", (unsigned long) pthread_self(),
+                       (unsigned long) gettid());
 
        set_affinity();
 
        rcu_register_thread();
+       assert(!rcu_read_ongoing());
 
        while (!test_go)
        {
@@ -235,14 +196,15 @@ void *thr_reader(void *_count)
 
        for (;;) {
                rcu_read_lock();
+               assert(rcu_read_ongoing());
                local_ptr = rcu_dereference(test_rcu_pointer);
-               debug_yield_read();
+               rcu_debug_yield_read();
                if (local_ptr)
-                       assert(local_ptr->a == 8);
+                       assert(*local_ptr == 8);
                if (caa_unlikely(rduration))
                        loop_sleep(rduration);
                rcu_read_unlock();
-               nr_reads++;
+               URCU_TLS(nr_reads)++;
                if (caa_unlikely(!test_duration_read()))
                        break;
        }
@@ -253,9 +215,10 @@ void *thr_reader(void *_count)
        rcu_register_thread();
        rcu_unregister_thread();
 
-       *count = nr_reads;
+       *count = URCU_TLS(nr_reads);
        printf_verbose("thread_end %s, thread id : %lx, tid %lu\n",
-                       "reader", pthread_self(), (unsigned long)gettid());
+                       "reader", (unsigned long) pthread_self(),
+                       (unsigned long) gettid());
        return ((void*)1);
 
 }
@@ -263,10 +226,11 @@ void *thr_reader(void *_count)
 void *thr_writer(void *_count)
 {
        unsigned long long *count = _count;
-       struct test_array *new, *old;
+       int *new, *old;
 
        printf_verbose("thread_begin %s, thread id : %lx, tid %lu\n",
-                       "writer", pthread_self(), (unsigned long)gettid());
+                       "writer", (unsigned long) pthread_self(),
+                       (unsigned long) gettid());
 
        set_affinity();
 
@@ -276,18 +240,17 @@ void *thr_writer(void *_count)
        cmm_smp_mb();
 
        for (;;) {
-               rcu_copy_mutex_lock();
-               new = test_array_alloc();
-               new->a = 8;
+               new = malloc(sizeof(int));
+               assert(new);
+               *new = 8;
                old = rcu_xchg_pointer(&test_rcu_pointer, new);
                if (caa_unlikely(wduration))
                        loop_sleep(wduration);
                synchronize_rcu();
                if (old)
-                       old->a = 0;
-               test_array_free(old);
-               rcu_copy_mutex_unlock();
-               nr_writes++;
+                       *old = 0;
+               free(old);
+               URCU_TLS(nr_writes)++;
                if (caa_unlikely(!test_duration_write()))
                        break;
                if (caa_unlikely(wdelay))
@@ -295,8 +258,9 @@ void *thr_writer(void *_count)
        }
 
        printf_verbose("thread_end %s, thread id : %lx, tid %lu\n",
-                       "writer", pthread_self(), (unsigned long)gettid());
-       *count = nr_writes;
+                       "writer", (unsigned long) pthread_self(),
+                       (unsigned long) gettid());
+       *count = URCU_TLS(nr_writes);
        return ((void*)2);
 }
 
@@ -352,10 +316,10 @@ int main(int argc, char **argv)
                switch (argv[i][1]) {
 #ifdef DEBUG_YIELD
                case 'r':
-                       yield_active |= YIELD_READ;
+                       rcu_yield_active |= RCU_YIELD_READ;
                        break;
                case 'w':
-                       yield_active |= YIELD_WRITE;
+                       rcu_yield_active |= RCU_YIELD_WRITE;
                        break;
 #endif
                case 'a':
@@ -400,9 +364,9 @@ int main(int argc, char **argv)
        printf_verbose("Writer delay : %lu loops.\n", wdelay);
        printf_verbose("Reader duration : %lu loops.\n", rduration);
        printf_verbose("thread %-6s, thread id : %lx, tid %lu\n",
-                       "main", pthread_self(), (unsigned long)gettid());
+                       "main", (unsigned long) pthread_self(),
+                       (unsigned long)gettid());
 
-       test_array = calloc(1, sizeof(*test_array) * ARRAY_SIZE);
        tid_reader = malloc(sizeof(*tid_reader) * nr_readers);
        tid_writer = malloc(sizeof(*tid_writer) * nr_writers);
        count_reader = malloc(sizeof(*count_reader) * nr_readers);
@@ -452,8 +416,7 @@ int main(int argc, char **argv)
                argv[0], duration, nr_readers, rduration, wduration,
                nr_writers, wdelay, tot_reads, tot_writes,
                tot_reads + tot_writes);
-       test_array_free(test_rcu_pointer);
-       free(test_array);
+       free(test_rcu_pointer);
        free(tid_reader);
        free(tid_writer);
        free(count_reader);
This page took 0.025585 seconds and 4 git commands to generate.