General Purpose library for Freestanding C++ and POSIX systems
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

82 rivejä
1.5 KiB

#pragma once
#include "gp/vfs/process_data.hpp"
#include <atomic>
class runqueue{
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*>;
struct topic_list{
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
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();
node->release();
return true;
} else {
ed->release();
node->release();
return false;
}
} else return false;
} else {
if(end.compare_exchange_strong(ed, node)) {
start.store(node);
node->release();
return true;
} else {
return false;
}
}
}
};
topic_list running;
topic_list waiting;
};