From 329c41c3ef087be3d6e30c3ffbb95855fcba49b4 Mon Sep 17 00:00:00 2001
From: Florian Fischer <florian.fl.fischer@fau.de>
Date: Tue, 17 Nov 2020 10:36:32 +0100
Subject: [PATCH] [worker] register each worker thread for userspace RCU using
 the default flavor

The default flavor is the preferred way to use the userspace library it uses
the sys_membarrier syscall or falls back to using userspace membarriers.

This adds the liburcu dependency which must be installed regardless the
'liburcu' meson option.
---
 .gitlab-ci.yml    | 2 ++
 emper/Emper.hpp   | 8 ++++++++
 emper/Runtime.cpp | 5 +++++
 emper/meson.build | 2 +-
 iwyu-mappings.imp | 1 +
 meson.build       | 4 +++-
 meson_options.txt | 6 ++++++
 7 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index b9c7200f..3a03bf28 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,6 +1,8 @@
 image: "flowdalic/debian-dev:1.13"
 
 before_script:
+  - apt update && apt install -y pkg-config
+  - apt install -y -t testing liburcu-dev
   - |
     readarray TOOLS <<EOF
     c++
diff --git a/emper/Emper.hpp b/emper/Emper.hpp
index 76fa35e3..d5c3dc57 100644
--- a/emper/Emper.hpp
+++ b/emper/Emper.hpp
@@ -22,4 +22,12 @@ static const bool WORKER_SLEEP =
 #endif
 		;
 
+static const bool LIBURCU =
+#ifdef EMPER_LIBURCU
+		true
+#else
+		false
+#endif
+		;
+
 }	 // namespace emper
diff --git a/emper/Runtime.cpp b/emper/Runtime.cpp
index 041bcc4b..2cc9e480 100644
--- a/emper/Runtime.cpp
+++ b/emper/Runtime.cpp
@@ -8,6 +8,7 @@
 // Non portable.
 #include <sched.h>				// for cpu_set_t, CPU_SET, CPU_ZERO
 #include <sys/sysinfo.h>	// for get_nprocs
+#include <urcu.h>					// for rcu_register_thread
 
 #include <cstdlib>	// for rand, srand, abort
 #include <cstring>
@@ -78,6 +79,10 @@ Runtime::Runtime(workerid_t workerCount, RuntimeStrategy& strategy, unsigned int
 		workerIds[i] = i;
 
 		auto thread_function = [](void* voidWorkerId) -> void* {
+			if constexpr (emper::LIBURCU) {
+				rcu_register_thread();
+			}
+
 			return currentRuntime->workerLoop(voidWorkerId);
 		};
 		errno = pthread_create(&threads[i], &attr, thread_function, &workerIds[i]);
diff --git a/emper/meson.build b/emper/meson.build
index eeee83e0..f73891a7 100644
--- a/emper/meson.build
+++ b/emper/meson.build
@@ -45,7 +45,7 @@ emper = library(
   [emper_cpp_sources, emper_generated_files],
   emper_asm_objects,
   include_directories: emper_all_include,
-  dependencies: thread_dep,
+  dependencies: emper_dependencies,
   install: true,
 )
 
diff --git a/iwyu-mappings.imp b/iwyu-mappings.imp
index 8a64523b..3b0d99be 100644
--- a/iwyu-mappings.imp
+++ b/iwyu-mappings.imp
@@ -1,4 +1,5 @@
 [
 	{ include: ["<bits/getopt_core.h>", "private", "<unistd.h>", "public"] },
 	{ include: ["@<gtest/.*>", "private", "<gtest/gtest.h>", "public"] },
+	{ include: ["<urcu/map/urcu-memb.h>", "private", "<urcu.h>", "public"] },
 ]
diff --git a/meson.build b/meson.build
index 325105c8..4bb842e1 100644
--- a/meson.build
+++ b/meson.build
@@ -12,12 +12,14 @@ project('EMPER', 'c', 'cpp',
 add_project_arguments('-Wno-non-virtual-dtor', language: 'cpp')
 
 thread_dep = dependency('threads')
-emper_dependencies = [thread_dep]
+liburcu_dep = dependency('liburcu')
+emper_dependencies = [thread_dep, liburcu_dep]
 
 run_target('iwyu',
 		   command: 'tools/check-iwyu')
 
 conf_data = configuration_data()
+conf_data.set('EMPER_LIBURCU', get_option('liburcu'))
 conf_data.set('EMPER_WORKER_SLEEP', get_option('worker_sleep'))
 conf_data.set('EMPER_LOCKED_WS_QUEUE', get_option('locked_ws_queue'))
 conf_data.set('EMPER_OVERFLOW_QUEUE', get_option('overflow_queue'))
diff --git a/meson_options.txt b/meson_options.txt
index 98a9ca15..4eadf18e 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -1,3 +1,9 @@
+option(
+  'liburcu',
+  type: 'boolean',
+  value: true,
+  description: 'Register worker threads for the default userspace RCU flavor',
+)
 option(
   'worker_sleep',
   type: 'boolean',
-- 
GitLab