summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVegard Storheil Eriksen <zyp@jvnv.net>2022-09-10 17:11:47 +0200
committerVegard Storheil Eriksen <zyp@jvnv.net>2022-09-10 17:11:47 +0200
commit4185927983fa5cd4b39887d62628af0056ce2d0b (patch)
treee82781a8a4102ec5055dd52f9ac19184378832b0
parentcaf7ac27916a1afc0cad72f4b6ac21c8404faf70 (diff)
async: Add queue.
-rw-r--r--async/queue.h59
1 files changed, 59 insertions, 0 deletions
diff --git a/async/queue.h b/async/queue.h
new file mode 100644
index 0000000..965e9b9
--- /dev/null
+++ b/async/queue.h
@@ -0,0 +1,59 @@
+#pragma once
+
+template <typename T, std::size_t N>
+struct queue {
+ std::array<T, N> data;
+ volatile std::size_t put_idx;
+ volatile std::size_t get_idx;
+
+ async_flag put_flag;
+ async_flag get_flag;
+
+ constexpr std::size_t _inc(std::size_t n) {
+ return n + 1 < N ? n + 1 : 0;
+ }
+
+ bool empty() {
+ return put_idx == get_idx;
+ }
+
+ bool full() {
+ return _inc(put_idx) == get_idx;
+ }
+
+ bool put(T v) {
+ if(full()) {
+ return false;
+ }
+
+ data[put_idx] = v;
+ put_idx = _inc(put_idx);
+ put_flag.set();
+ return true;
+ }
+
+ bool get(T& v) {
+ if(empty()) {
+ return false;
+ }
+
+ v = data[get_idx];
+ get_idx = _inc(get_idx);
+ get_flag.set();
+ return true;
+ }
+
+ async<> async_put(T v) {
+ while(!put(v)) {
+ co_await get_flag;
+ }
+ }
+
+ async<T> async_get() {
+ T v;
+ while(!get(v)) {
+ co_await put_flag;
+ }
+ co_return v;
+ }
+};