summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Qin <richard.qin.x@gmail.com>2026-05-13 16:24:57 +0800
committerRichard Qin <richard.qin.x@gmail.com>2026-05-13 16:24:57 +0800
commit7ab355b15896edbd7e2927bd3609878a7ad808d7 (patch)
treec6996903d4540e66d24d53e719a26028b1fb2855
parentd4eb22af1b6d21546e58ee73d793d962016eb27a (diff)
downloadlume-7ab355b15896edbd7e2927bd3609878a7ad808d7.tar.gz
lume-7ab355b15896edbd7e2927bd3609878a7ad808d7.tar.xz
feat: implement O1RunQueue and RunQueue classes for task scheduling
-rw-r--r--na/kernel/sched_internal.h115
1 files changed, 115 insertions, 0 deletions
diff --git a/na/kernel/sched_internal.h b/na/kernel/sched_internal.h
new file mode 100644
index 0000000..514b613
--- /dev/null
+++ b/na/kernel/sched_internal.h
@@ -0,0 +1,115 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/* Copyright (C) 2026 Richard Qin */
+
+#pragma once
+
+#include <lume/types.h>
+#include <lume/list.h>
+#include <lume/sched.h>
+#include <lume/config.h>
+#include <lume/bitops.h>
+#include <lume/task.h>
+#include <kernel/sync/spinlock.h>
+
+class O1RunQueue {
+public:
+ void init() {
+ bitmap_ = 0;
+ nr_running_ = 0;
+ for (int p = 0; p < kNumPriorities; p++) {
+ queues_[p].init();
+ }
+ }
+
+ void enqueue(TaskControlBlock* task) {
+ int prio = task->priority;
+
+ list_node* head = &queues_[prio];
+ task->run_link.prev = head->prev;
+ task->run_link.next = head;
+ head->prev->next = &task->run_link;
+ head->prev = &task->run_link;
+
+ bitmap_ |= (1U << prio);
+ nr_running_++;
+
+ task->state = TaskState::Runnable;
+ }
+
+ void dequeue(TaskControlBlock* task) {
+ int prio = task->priority;
+
+ task->run_link.prev->next = task->run_link.next;
+ task->run_link.next->prev = task->run_link.prev;
+ task->run_link.init();
+
+ if (queues_[prio].is_empty()) {
+ bitmap_ &= ~(1U << prio);
+ }
+
+ if (nr_running_ > 0) {
+ nr_running_--;
+ }
+ }
+
+ TaskControlBlock* pick_next() const {
+ if (bitmap_ == 0) {
+ return nullptr;
+ }
+
+ int prio = lume::ctz32(bitmap_);
+ list_node* node = queues_[prio].next;
+ return list_entry<TaskControlBlock, &TaskControlBlock::run_link>(node);
+ }
+
+ uint32 nr_running() const { return nr_running_; }
+
+private:
+ uint32 bitmap_ = 0;
+ list_node queues_[kNumPriorities];
+ uint32 nr_running_ = 0;
+};
+
+class RunQueue {
+public:
+ void init(uint32 cpu_id) {
+ lock_.init("RunQueue");
+ cpu_id_ = cpu_id;
+ nr_running_ = 0;
+ need_resched_ = false;
+ current_ = nullptr;
+ idle_ = nullptr;
+ }
+
+ Spinlock& lock() { return lock_; }
+
+ uint32 cpu_id() const { return cpu_id_; }
+
+ uint32 nr_running() const { return nr_running_; }
+ void inc_running() { nr_running_++; }
+ void dec_running() { if (nr_running_ > 0) nr_running_--; }
+
+ bool need_resched() const { return need_resched_; }
+ void set_need_resched(bool v) { need_resched_ = v; }
+ void clear_need_resched() { need_resched_ = false; }
+
+ TaskControlBlock* current() const { return current_; }
+ void set_current(TaskControlBlock* task) { current_ = task; }
+
+ TaskControlBlock* idle() const { return idle_; }
+ void set_idle(TaskControlBlock* task) { idle_ = task; }
+
+ O1RunQueue& o1() { return o1_; }
+ const O1RunQueue& o1() const { return o1_; }
+
+private:
+ Spinlock lock_;
+ uint32 cpu_id_ = 0;
+ uint32 nr_running_ = 0;
+ bool need_resched_ = false;
+
+ TaskControlBlock* current_ = nullptr;
+ TaskControlBlock* idle_ = nullptr;
+
+ O1RunQueue o1_;
+};