|
|
- #pragma once
-
- #include "gp/vfs/process_data.hpp"
-
- #include <atomic>
-
- namespace gp {
- struct topic_list{
- struct node{
- std::atomic_bool is_locked;
- gp::process_data* value;
- std::atomic<struct node*> next;
-
- bool try_acquire() noexcept {
- bool expected = false;
- return !(is_locked.compare_exchange_strong(expected, true));
- }
-
- void release() noexcept {
- is_locked.store(false);
- }
- };
-
- using node_ptr = struct node*;
- using node_ptr_rep = std::atomic<struct node*>;
-
- node_ptr_rep start;
- node_ptr_rep end;
-
- // NODES ARE ACQUIRED ON POP
- node_ptr try_pop() {
- auto ptr = start.load();
- if(!ptr) return nullptr;
-
- if(ptr->try_acquire()) {
- auto replace = ptr->next.load();
- auto expected = ptr;
- if(end.load() == ptr) {
- end.store(nullptr);
- }
- if(start.compare_exchange_strong(expected, replace)) {
- return ptr;
- } else {
- return nullptr;
- }
- } else {
- return nullptr;
- }
- }
-
- // ONLY PUSH ACQUIRED NODES,
- // RELEASE WHEN NO LONGER IN USE
- bool try_push(node_ptr node) {
- auto ed = end.load();
- if(ed) {
- if(ed->try_acquire()) {
- node->next.store(ed);
- if(end.compare_exchange_strong(ed, node)) {
- ed->release();
- return true;
- } else {
- ed->release();
- return false;
- }
- } else return false;
- } else {
- if(end.compare_exchange_strong(ed, node)) {
- start.store(node);
- return true;
- } else {
- return false;
- }
- }
- }
- };
- }
|