|
|
- #pragma once
- #include "gp/system/system.hpp"
-
- namespace gp{
-
- class simple_scheduling : public gp::scheduling_scheme {
- struct locked_circular_buffer {
- std::atomic_bool lock;
- gp::array<gp::topic_list::node_ptr, gp_config::limits::max_processes> processes;
- size_t read_idx = 0;
- size_t write_idx = 0;
-
- void push(gp::topic_list::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)){}
- }
-
- gp::topic_list::node_ptr pop() {
- bool t = true;
- bool f = false;
- gp::topic_list::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();
- }
- }
- while(not lock.compare_exchange_strong(t,f)){}
- return ret;
- }
-
- };
-
-
- locked_circular_buffer running;
- locked_circular_buffer waiting;
- locked_circular_buffer to_clean;
- locked_circular_buffer naughty;
- system* sys = nullptr;
-
- public:
- simple_scheduling()
- {}
-
- virtual void link(system& value) {
- gp_config::assertion(!(sys), "Double linkage detected");
- sys = &value;
-
- sys->process_managers.emplace_back(*sys,0);
- }
-
- virtual gp::topic_list::node_ptr one(size_t) {
- auto v = running.pop();
- do{
- if(v) return v;
- v = running.pop();
- }while(true);
- }
-
- virtual void push(gp::topic_list::node_ptr node) {
- running.push(node);
- }
-
- virtual gp::topic_list::node_ptr next(size_t, gp::topic_list::node_ptr current) {
- switch(current->value->state) {
- case process_status::inactive:
- case process_status::running:
- running.push(current);
- break;
- case process_status::finished:
- to_clean.push(current);
- break;
- case process_status::zombie:
- naughty.push(current);
- break;
- case process_status::waiting:
- waiting.push(current);
- break;
- }
- return one(0);
- }
-
- virtual gp::scheduler& current_scheduler() {
- return sys->process_managers[0];
- }
- };
- }
|