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.

89 lines
2.2 KiB

  1. #pragma once
  2. #include "gp/ipc/bottleneck.hpp"
  3. #include "gp/system/system.hpp"
  4. namespace gp{
  5. namespace system {
  6. class simple_scheduling : public gp::system::scheduling_scheme {
  7. struct locked_circular_buffer {
  8. gp::array<gp::system::task_queue::node_ptr, gp_config::limits::max_processes> processes;
  9. size_t read_idx = 0;
  10. size_t write_idx = 0;
  11. fast_bottleneck lock;
  12. void push(gp::system::task_queue::node_ptr node) {
  13. auto guard = lock_guard(lock);
  14. gp_config::assertion((write_idx + 1)%processes.size() != read_idx, "bad push to circular buffer");
  15. processes[write_idx] = node;
  16. write_idx=(write_idx+1)%processes.size();
  17. }
  18. gp::system::task_queue::node_ptr pop() {
  19. gp::system::task_queue::node_ptr ret;
  20. auto guard = lock_guard(lock);
  21. if(read_idx == write_idx) {
  22. ret = nullptr;
  23. } else {
  24. ret = processes[read_idx];
  25. read_idx=(read_idx+1)%processes.size();
  26. }
  27. return ret;
  28. }
  29. };
  30. locked_circular_buffer running;
  31. locked_circular_buffer waiting;
  32. locked_circular_buffer to_clean;
  33. locked_circular_buffer naughty;
  34. system* sys = nullptr;
  35. public:
  36. simple_scheduling()
  37. {}
  38. virtual void link(system& value) {
  39. gp_config::assertion(!(sys), "Double linkage detected");
  40. sys = &value;
  41. sys->process_managers.emplace_back(*sys,0);
  42. }
  43. virtual gp::system::task_queue::node_ptr one(size_t) {
  44. auto v = running.pop();
  45. do{
  46. if(v) return v;
  47. v = running.pop();
  48. }while(true);
  49. }
  50. virtual void push(gp::system::task_queue::node_ptr node) {
  51. running.push(node);
  52. }
  53. virtual gp::system::task_queue::node_ptr next(size_t, gp::system::task_queue::node_ptr current) {
  54. switch(current->value->state) {
  55. case process_status::inactive:
  56. case process_status::running:
  57. running.push(current);
  58. break;
  59. case process_status::finished:
  60. to_clean.push(current);
  61. break;
  62. case process_status::zombie:
  63. naughty.push(current);
  64. break;
  65. case process_status::waiting:
  66. waiting.push(current);
  67. break;
  68. }
  69. return one(0);
  70. }
  71. virtual gp::system::scheduler& current_scheduler() {
  72. return sys->process_managers[0];
  73. }
  74. };
  75. }
  76. }