General Purpose library for Freestanding C++ and POSIX systems
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 

76 行
1.4 KiB

#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;
}
}
}
};
}