Basic side rcu test
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Thu, 24 Nov 2022 19:14:15 +0000 (14:14 -0500)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Thu, 24 Nov 2022 19:14:15 +0000 (14:14 -0500)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
tests/regression/Makefile
tests/regression/side-rcu-test.c

index 4b74ec6469cbd17c51a1477b20ab2e23d255fd9c..5d796348743292cdf3aab7198cc566b6ccdb1a35 100644 (file)
@@ -9,7 +9,7 @@ side-rcu-test.o: side-rcu-test.c $(HEADERS)
        $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
 
 side-rcu-test: side-rcu-test.o ../../src/rcu.o ../../src/smp.o
-       $(CC) $(CFLAGS) -o $@ $^ -lrseq
+       $(CC) $(CFLAGS) -pthread -o $@ $^ -lrseq
 
 .PHONY: clean
 
index 4d6b2817f666ffc4a180ca5a8e567051decae811..a623896859dd0d373c40b58de2f4e5ab2ba1fc23 100644 (file)
@@ -1,6 +1,161 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright 2022 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ */
+
+#include <pthread.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+static int nr_reader_threads = 1;
+static int nr_writer_threads = 1;
+static int duration_s = 10;
+
+static volatile int start_test, stop_test;
+
+struct thread_ctx {
+       pthread_t thread_id;
+       uint64_t count;
+};
+
 #include "../../src/rcu.h"
 
+static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
+
+static struct side_rcu_gp_state test_rcu_gp;
+
+#define POISON_VALUE   0x55
+
+struct test_data {
+       int v;
+};
+
+static struct test_data *p;
+
+static
+void *test_reader_thread(void *arg)
+{
+       struct thread_ctx *thread_ctx = (struct thread_ctx *) arg;
+       uint64_t count = 0;
+
+       while (!start_test) { }
+
+       while (!stop_test) {
+               int period;
+
+               period = side_rcu_read_begin(&test_rcu_gp);
+               //TODO
+               side_rcu_read_end(&test_rcu_gp, period);
+               count++;
+       }
+       thread_ctx->count = count;
+       return NULL;
+}
+
+static
+void *test_writer_thread(void *arg)
+{
+       struct thread_ctx *thread_ctx = (struct thread_ctx *) arg;
+       uint64_t count = 0;
+
+       while (!start_test) { }
+
+       while (!stop_test) {
+               struct test_data *new_data, *old_data;
+
+               new_data = calloc(1, sizeof(struct test_data));
+               if (!new_data)
+                       abort();
+
+               pthread_mutex_lock(&lock);
+               old_data = p;
+               if (old_data)
+                       new_data->v = old_data->v ^ 1;  /* 0 or 1 */
+               side_rcu_assign_pointer(p, new_data);
+               pthread_mutex_unlock(&lock);
+
+               side_rcu_wait_grace_period(&test_rcu_gp);
+
+               if (old_data) {
+                       old_data->v = POISON_VALUE;
+                       free(old_data);
+               }
+               count++;
+       }
+       thread_ctx->count = count;
+       return NULL;
+}
+
 int main(int argc, char **argv)
 {
+       struct thread_ctx *reader_ctx;
+       struct thread_ctx *writer_ctx;
+       int i, ret;
+       int sleep_s = duration_s;
+       uint64_t read_tot = 0, write_tot = 0;
+
+       side_rcu_gp_init(&test_rcu_gp);
+       //TODO: parse command line args.
+
+       reader_ctx = calloc(nr_reader_threads, sizeof(struct thread_ctx));
+       if (!reader_ctx)
+               abort();
+       writer_ctx = calloc(nr_writer_threads, sizeof(struct thread_ctx));
+       if (!writer_ctx)
+               abort();
+
+
+       for (i = 0; i < nr_reader_threads; i++) {
+               ret = pthread_create(&reader_ctx[i].thread_id, NULL, test_reader_thread, &reader_ctx[i]);
+               if (ret) {
+                       errno = ret;
+                       perror("pthread_create");
+                       abort();
+               }
+       }
+       for (i = 0; i < nr_writer_threads; i++) {
+               ret = pthread_create(&writer_ctx[i].thread_id, NULL, test_writer_thread, &writer_ctx[i]);
+               if (ret) {
+                       errno = ret;
+                       perror("pthread_create");
+                       abort();
+               }
+       }
+
+       start_test = 1;
+
+       while (sleep_s > 0) {
+               sleep_s = sleep(sleep_s);
+       }
+
+       stop_test = 1;
+
+       for (i = 0; i < nr_reader_threads; i++) {
+               void *res;
+
+               ret = pthread_join(reader_ctx[i].thread_id, &res);
+               if (ret) {
+                       errno = ret;
+                       perror("pthread_join");
+                       abort();
+               }
+               read_tot += reader_ctx[i].count;
+       }
+       for (i = 0; i < nr_writer_threads; i++) {
+               void *res;
+
+               ret = pthread_join(writer_ctx[i].thread_id, &res);
+               if (ret) {
+                       errno = ret;
+                       perror("pthread_join");
+                       abort();
+               }
+               write_tot += writer_ctx[i].count;
+       }
+       printf("Summary: duration: %d, nr_reader_threads: %d, nr_writer_threads: %d, reads: %" PRIu64 ", writes: %" PRIu64 "\n",
+               duration_s, nr_reader_threads, nr_writer_threads, read_tot, write_tot);
+       free(reader_ctx);
+       free(writer_ctx);
+       side_rcu_gp_exit(&test_rcu_gp);
        return 0;
 }
This page took 0.030475 seconds and 4 git commands to generate.