From 513faa92c73ed1c334a1dc8722e3b162c5ec29be Mon Sep 17 00:00:00 2001 From: wnstngs <64602598+wnstngs@users.noreply.github.com> Date: Wed, 7 Oct 2026 10:24:50 +0300 Subject: [PATCH] kernel: use list.h for scheduling run queues --- kernel-src/include/kernel/scheduler.h | 7 +-- kernel-src/include/kernel/thread.h | 4 +- kernel-src/sys/scheduler/queue.c | 77 +++++++++------------------ kernel-src/sys/scheduler/scheduler.c | 18 +++++-- 4 files changed, 41 insertions(+), 65 deletions(-) diff --git a/kernel-src/include/kernel/scheduler.h b/kernel-src/include/kernel/scheduler.h index c78936c5..6060ea69 100644 --- a/kernel-src/include/kernel/scheduler.h +++ b/kernel-src/include/kernel/scheduler.h @@ -20,15 +20,12 @@ #define SCHED_SLEEP_TIME_LIMIT_CPU_US 1000 typedef struct { - struct { - thread_t *ins; - thread_t *run; - } queues[SCHED_RUN_QUEUE_SIZE]; + list_t queues[SCHED_RUN_QUEUE_SIZE]; bitmap_t thread_bitmap; } sched_run_queue_t; typedef struct { - thread_t *queues[SCHED_RUN_QUEUE_SIZE]; + list_t queues[SCHED_RUN_QUEUE_SIZE]; int ins; int run; size_t thread_count; diff --git a/kernel-src/include/kernel/thread.h b/kernel-src/include/kernel/thread.h index fa1588a7..911b4f30 100644 --- a/kernel-src/include/kernel/thread.h +++ b/kernel-src/include/kernel/thread.h @@ -7,6 +7,7 @@ #include #include #include +#include #define THREAD_FLAGS_QUEUED 1 #define THREAD_FLAGS_RUNNING 2 @@ -23,8 +24,7 @@ struct proc_t; typedef struct thread_t { void *kernelstacktop; - struct thread_t *next; - struct thread_t *prev; + list_node_t queue_node; struct thread_t *sleepnext; struct thread_t *sleepprev; struct thread_t *procnext; diff --git a/kernel-src/sys/scheduler/queue.c b/kernel-src/sys/scheduler/queue.c index 3641f331..c1d87496 100644 --- a/kernel-src/sys/scheduler/queue.c +++ b/kernel-src/sys/scheduler/queue.c @@ -54,16 +54,7 @@ static cpu_t *pick_cpu(thread_t *thread) { static void insert_in_run_queue(sched_run_queue_t *run_queue, thread_t *thread) { int idx = sched_thread_run_queue_index(thread->metrics.interactivity_score); - thread->prev = run_queue->queues[idx].ins; - - if (thread->prev) - thread->prev->next = thread; - else - run_queue->queues[idx].run = thread; - - thread->next = NULL; - run_queue->queues[idx].ins = thread; - + list_push_back(&run_queue->queues[idx], &thread->queue_node); bitmap_set(&run_queue->thread_bitmap, idx, 1); } @@ -72,14 +63,12 @@ static thread_t *pop_from_run_queue(sched_run_queue_t *run_queue) { if (idx == -1) return NULL; - thread_t *thread = run_queue->queues[idx].run; - - run_queue->queues[idx].run = thread->next; + list_node_t *node = run_queue->queues[idx].next; + thread_t *thread = container_of(node, thread_t, queue_node); - if (thread->next) { - thread->next->prev = NULL; - } else { - run_queue->queues[idx].ins = NULL; + list_remove(node); + + if (list_is_empty(&run_queue->queues[idx])) { bitmap_set(&run_queue->thread_bitmap, idx, 0); } @@ -91,23 +80,15 @@ static thread_t *steal_from_calendar_queue(sched_calendar_queue_t *calendar_queu return NULL; int run = calendar_queue->run; - - thread_t *thread = NULL; + do { - thread = calendar_queue->queues[run]; - thread_t *prev = NULL; - while (thread) { + list_for_each (&calendar_queue->queues[run], node) { + thread_t *thread = container_of(node, thread_t, queue_node); if (thread->cputarget) { - prev = thread; - thread = thread->next; continue; } - if (prev) - prev->next = thread->next; - else - calendar_queue->queues[run] = thread->next; - + list_remove(node); --calendar_queue->thread_count; return thread; } @@ -125,26 +106,18 @@ static thread_t *steal_from_run_queue(sched_run_queue_t *run_queue) { return NULL; for (; idx < SCHED_RUN_QUEUE_SIZE; ++idx) { - for (thread_t *search = run_queue->queues[idx].run; search; search = search->next) { - if (search->cputarget) + list_for_each (&run_queue->queues[idx], node) { + thread_t *thread = container_of(node, thread_t, queue_node); + if (thread->cputarget) { continue; - - if (search->next) { - search->next->prev = search->prev; - } else { - run_queue->queues[idx].ins = search->prev; } - if (search->prev) { - search->prev->next = search->next; - } else { - run_queue->queues[idx].run = search->next; - } - - if (run_queue->queues[idx].run == NULL) + list_remove(node); + if (list_is_empty(&run_queue->queues[idx])) { bitmap_set(&run_queue->thread_bitmap, idx, 0); + } - return search; + return thread; } } @@ -155,8 +128,7 @@ static thread_t *steal_from_run_queue(sched_run_queue_t *run_queue) { static void insert_in_calendar_queue(sched_calendar_queue_t *calendar_queue, thread_t *thread) { int idx = (calendar_queue->ins + thread->metrics.interactivity_score - SCHED_INTERACTIVITY_LIMIT) % SCHED_RUN_QUEUE_SIZE; - thread->next = calendar_queue->queues[idx]; - calendar_queue->queues[idx] = thread; + list_push_front(&calendar_queue->queues[idx], &thread->queue_node); ++calendar_queue->thread_count; } @@ -164,22 +136,21 @@ static thread_t *pop_from_calendar_queue(sched_calendar_queue_t *calendar_queue) if (calendar_queue->thread_count == 0) return NULL; - thread_t *thread; + list_node_t *node; do { - thread = calendar_queue->queues[calendar_queue->run]; - if (thread) - calendar_queue->queues[calendar_queue->run] = thread->next; - else + node = list_pop_front(&calendar_queue->queues[calendar_queue->run]); + if (node == NULL) { calendar_queue->run = (calendar_queue->run + 1) % SCHED_RUN_QUEUE_SIZE; + } if (calendar_queue->run == calendar_queue->ins) calendar_queue->ins = (calendar_queue->ins + 1) % SCHED_RUN_QUEUE_SIZE; - } while (thread == NULL); + } while (node == NULL); --calendar_queue->thread_count; - return thread; + return container_of(node, thread_t, queue_node); } // requires cpu queue to be locked diff --git a/kernel-src/sys/scheduler/scheduler.c b/kernel-src/sys/scheduler/scheduler.c index a7fd8ebd..481f6858 100644 --- a/kernel-src/sys/scheduler/scheduler.c +++ b/kernel-src/sys/scheduler/scheduler.c @@ -346,9 +346,17 @@ void sched_sleep_us(size_t us) { sched_yield(); } -static void set_up_bitmaps(void) { - __assert(bitmap_init(¤t_cpu()->rt_queue.thread_bitmap, SCHED_RUN_QUEUE_SIZE) == 0); - __assert(bitmap_init(¤t_cpu()->idle_queue.thread_bitmap, SCHED_RUN_QUEUE_SIZE) == 0); +static void set_up_queues(void) { + cpu_t *cpu = current_cpu(); + + for (size_t i = 0; i < SCHED_RUN_QUEUE_SIZE; ++i) { + list_init(&cpu->rt_queue.queues[i]); + list_init(&cpu->idle_queue.queues[i]); + list_init(&cpu->ts_queue.queues[i]); + } + + __assert(bitmap_init(&cpu->rt_queue.thread_bitmap, SCHED_RUN_QUEUE_SIZE) == 0); + __assert(bitmap_init(&cpu->idle_queue.thread_bitmap, SCHED_RUN_QUEUE_SIZE) == 0); } void sched_calendar_tick(context_t *, dpcarg_t); @@ -358,7 +366,7 @@ void sched_ap_entry() { SPINLOCK_INIT(current_cpu()->sched_lock); dpc_prepare(¤t_cpu()->reschedule_dpc, sched_reschedule_dpc); - set_up_bitmaps(); + set_up_queues(); current_cpu()->schedulerstack = mm_map(NULL, SCHEDULER_STACK_SIZE, MM_RANGE_FLAGS_ALLOCATE, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC, NULL); __assert(current_cpu()->schedulerstack); @@ -386,7 +394,7 @@ void sched_init() { SPINLOCK_INIT(sched_idle_cpu_bitmap_lock); dpc_prepare(¤t_cpu()->reschedule_dpc, sched_reschedule_dpc); - set_up_bitmaps(); + set_up_queues(); __assert(bitmap_init(&sched_idle_cpu_bitmap, arch_smp_get_cpu_count()) == 0);