Implement a lockless queue
This uses atomics to swap pointers from an array. It is safe against
process death, and concurent writes. It also uses signals to wakeup any
processes waiting for new data.
https://docs.google.com/document/d/10xulameLtEqjBFkm54UcN-5N-w5Q_XFNILvNf1Jl1Y4/edit#
Change-Id: Ie7b2aea6f869c1d84e0705aadb21d33fa8241b60
diff --git a/aos/ipc_lib/BUILD b/aos/ipc_lib/BUILD
index 6947df1..76c5324 100644
--- a/aos/ipc_lib/BUILD
+++ b/aos/ipc_lib/BUILD
@@ -164,6 +164,7 @@
cc_library(
name = "index",
+ srcs = ["index.cc"],
hdrs = ["index.h"],
)
@@ -176,3 +177,69 @@
"//aos/testing:test_logging",
],
)
+
+cc_library(
+ name = "lockless_queue",
+ srcs = [
+ "lockless_queue.cc",
+ "lockless_queue_memory.h",
+ ],
+ hdrs = ["lockless_queue.h"],
+ deps = [
+ ":aos_sync",
+ ":index",
+ "//aos:init",
+ "//aos/logging",
+ "//aos/time",
+ "//aos/util:compiler_memory_barrier",
+ ],
+)
+
+cc_library(
+ name = "queue_racer",
+ testonly = True,
+ srcs = [
+ "queue_racer.cc",
+ ],
+ hdrs = [
+ "queue_racer.h",
+ ],
+ deps = [
+ ":lockless_queue",
+ "//aos:event",
+ "//third_party/googletest:gtest",
+ ],
+)
+
+cc_test(
+ name = "lockless_queue_test",
+ timeout = "eternal",
+ srcs = ["lockless_queue_test.cc"],
+ deps = [
+ ":lockless_queue",
+ ":queue_racer",
+ ":signalfd",
+ "//aos:event",
+ "//aos/events:epoll",
+ "//aos/libc:aos_strsignal",
+ "//aos/testing:googletest",
+ "//aos/testing:prevent_exit",
+ "//aos/testing:test_logging",
+ ],
+)
+
+cc_test(
+ name = "lockless_queue_death_test",
+ srcs = ["lockless_queue_death_test.cc"],
+ deps = [
+ ":lockless_queue",
+ ":queue_racer",
+ ":signalfd",
+ "//aos:event",
+ "//aos/events:epoll",
+ "//aos/libc:aos_strsignal",
+ "//aos/testing:googletest",
+ "//aos/testing:prevent_exit",
+ "//aos/testing:test_logging",
+ ],
+)