|
|
@ -1,43 +1,33 @@ |
|
|
|
#pragma once
|
|
|
|
#include "gp/system/system.hpp"
|
|
|
|
|
|
|
|
// TODO: implement unsafe_bottleneck to use in the locked list
|
|
|
|
#include "gp/ipc/bottleneck.hpp"
|
|
|
|
#include "gp/system/system.hpp"
|
|
|
|
|
|
|
|
namespace gp{ |
|
|
|
namespace system { |
|
|
|
class simple_scheduling : public gp::system::scheduling_scheme { |
|
|
|
struct locked_circular_buffer { |
|
|
|
std::atomic_bool lock; |
|
|
|
gp::array<gp::system::task_queue::node_ptr, gp_config::limits::max_processes> processes; |
|
|
|
size_t read_idx = 0; |
|
|
|
size_t write_idx = 0; |
|
|
|
fast_bottleneck lock; |
|
|
|
|
|
|
|
void push(gp::system::task_queue::node_ptr node) { |
|
|
|
bool t = true; |
|
|
|
bool f = false; |
|
|
|
while(not lock.compare_exchange_strong(f,t)){} |
|
|
|
{ |
|
|
|
gp_config::assertion((write_idx + 1)%processes.size() != read_idx, "bad push to circular buffer"); |
|
|
|
processes[write_idx] = node; |
|
|
|
write_idx=(write_idx+1)%processes.size(); |
|
|
|
} |
|
|
|
while(not lock.compare_exchange_strong(t,f)){} |
|
|
|
auto guard = lock_guard(lock); |
|
|
|
gp_config::assertion((write_idx + 1)%processes.size() != read_idx, "bad push to circular buffer"); |
|
|
|
processes[write_idx] = node; |
|
|
|
write_idx=(write_idx+1)%processes.size(); |
|
|
|
} |
|
|
|
|
|
|
|
gp::system::task_queue::node_ptr pop() { |
|
|
|
bool t = true; |
|
|
|
bool f = false; |
|
|
|
gp::system::task_queue::node_ptr ret; |
|
|
|
while(not lock.compare_exchange_strong(f,t)){} |
|
|
|
{ |
|
|
|
if(read_idx == write_idx) { |
|
|
|
ret = nullptr; |
|
|
|
} else { |
|
|
|
ret = processes[read_idx]; |
|
|
|
read_idx=(read_idx+1)%processes.size(); |
|
|
|
} |
|
|
|
auto guard = lock_guard(lock); |
|
|
|
if(read_idx == write_idx) { |
|
|
|
ret = nullptr; |
|
|
|
} else { |
|
|
|
ret = processes[read_idx]; |
|
|
|
read_idx=(read_idx+1)%processes.size(); |
|
|
|
} |
|
|
|
while(not lock.compare_exchange_strong(t,f)){} |
|
|
|
return ret; |
|
|
|
} |
|
|
|
|
|
|
|