diff options
author | Vegard Storheil Eriksen <zyp@jvnv.net> | 2022-09-10 17:11:47 +0200 |
---|---|---|
committer | Vegard Storheil Eriksen <zyp@jvnv.net> | 2022-09-10 17:11:47 +0200 |
commit | 4185927983fa5cd4b39887d62628af0056ce2d0b (patch) | |
tree | e82781a8a4102ec5055dd52f9ac19184378832b0 | |
parent | caf7ac27916a1afc0cad72f4b6ac21c8404faf70 (diff) |
async: Add queue.
-rw-r--r-- | async/queue.h | 59 |
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; + } +}; |