Advertisement
mishakov

pmOS scheduling

May 14th, 2024 (edited)
367
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.33 KB | None | 0 0
  1. void reschedule()
  2. {
  3.     auto *const cpu_str         = get_cpu_struct();
  4.     const auto current_priority = cpu_str->current_task->priority;
  5.  
  6.     auto const new_task = cpu_str->atomic_pick_highest_priority(current_priority - 1);
  7.     if (new_task) {
  8.         auto const current_task = cpu_str->current_task;
  9.  
  10.         // It might be fine to lock the locks separately
  11.         Auto_Lock_Scope_Double l(current_task->sched_lock, new_task->sched_lock);
  12.  
  13.         new_task->switch_to();
  14.         push_ready(current_task);
  15.     }
  16.  
  17.     while (cpu_str->current_task->status == TaskStatus::TASK_DYING) {
  18.         auto t = cpu_str->current_task;
  19.         t->cleanup();
  20.  
  21.         find_new_process();
  22.     }
  23. }
  24.  
  25. klib::shared_ptr<TaskDescriptor> CPU_Info::atomic_pick_highest_priority(priority_t min)
  26. {
  27.     const priority_t max_priority = sched_queues.size() - 1;
  28.     const priority_t to_priority  = min > max_priority ? max_priority : min;
  29.  
  30.     for (priority_t i = 0; i <= to_priority; ++i) {
  31.         klib::shared_ptr<TaskDescriptor> task;
  32.         {
  33.             auto &queue = sched_queues[i];
  34.  
  35.             Auto_Lock_Scope l(queue.lock);
  36.  
  37.             task = queue.pop_front();
  38.         }
  39.  
  40.         if (task != klib::shared_ptr<TaskDescriptor>(nullptr))
  41.             return task;
  42.  
  43.         {
  44.             auto &queue = global_sched_queues[i];
  45.  
  46.             Auto_Lock_Scope l(queue.lock);
  47.  
  48.             task = queue.pop_front();
  49.         }
  50.  
  51.         if (task != klib::shared_ptr<TaskDescriptor>(nullptr))
  52.             return task;
  53.     }
  54.  
  55.     return nullptr;
  56. }
  57.  
  58. void TaskDescriptor::switch_to()
  59. {
  60.     CPU_Info *c = get_cpu_struct();
  61.     if (c->current_task->page_table != page_table) {
  62.         page_table->atomic_active_sum(1);
  63.         c->current_task->page_table->atomic_active_sum(-1);
  64.         page_table->apply();
  65.         c->paging_rcu_cpu.quiet(paging_rcu, c->cpu_id);
  66.     }
  67.  
  68.     c->current_task->before_task_switch();
  69.  
  70.     // Switch task
  71.     if (status != TaskStatus::TASK_DYING)
  72.         // If the task is dying, don't change its status and let the scheduler handle it when
  73.         // returning from the kernel
  74.         status = TaskStatus::TASK_RUNNING;
  75.  
  76.     c->current_task_priority = priority;
  77.     c->current_task          = weak_self.lock();
  78.  
  79.     this->after_task_switch();
  80.  
  81.     start_timer(assign_quantum_on_priority(priority));
  82. }
  83.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement