This commit is contained in:
2026-04-09 22:35:11 +08:00
parent e9a813a123
commit 60f028db64
7 changed files with 236 additions and 1 deletions

View File

@@ -2,6 +2,7 @@
#include <clks/cpu.h>
#include <clks/interrupts.h>
#include <clks/log.h>
#include <clks/scheduler.h>
#include <clks/types.h>
#define CLKS_IDT_ENTRY_COUNT 256U

View File

@@ -6,6 +6,7 @@
#include <clks/kernel.h>
#include <clks/log.h>
#include <clks/pmm.h>
#include <clks/scheduler.h>
#include <clks/serial.h>
#include <clks/tty.h>
#include <clks/types.h>
@@ -15,6 +16,7 @@ void clks_kernel_main(void) {
const struct limine_memmap_response *boot_memmap;
struct clks_pmm_stats pmm_stats;
struct clks_heap_stats heap_stats;
struct clks_scheduler_stats sched_stats;
void *heap_probe = CLKS_NULL;
clks_serial_init();
@@ -31,7 +33,7 @@ void clks_kernel_main(void) {
clks_tty_init();
}
clks_log(CLKS_LOG_INFO, "BOOT", "CLEONOS STAGE3 START");
clks_log(CLKS_LOG_INFO, "BOOT", "CLEONOS STAGE4 START");
if (boot_fb == CLKS_NULL) {
clks_log(CLKS_LOG_WARN, "VIDEO", "NO FRAMEBUFFER FROM LIMINE");
@@ -78,6 +80,19 @@ void clks_kernel_main(void) {
clks_kfree(heap_probe);
}
clks_scheduler_init();
if (clks_scheduler_add_kernel_task("klogd", 4U) == CLKS_FALSE) {
clks_log(CLKS_LOG_WARN, "SCHED", "FAILED TO ADD KLOGD TASK");
}
if (clks_scheduler_add_kernel_task("kworker", 3U) == CLKS_FALSE) {
clks_log(CLKS_LOG_WARN, "SCHED", "FAILED TO ADD KWORKER TASK");
}
sched_stats = clks_scheduler_get_stats();
clks_log_hex(CLKS_LOG_INFO, "SCHED", "TASK_COUNT", sched_stats.task_count);
clks_interrupts_init();
clks_log(CLKS_LOG_INFO, "INT", "IDT + PIC INITIALIZED");

138
clks/kernel/scheduler.c Normal file
View File

@@ -0,0 +1,138 @@
#include <clks/log.h>
#include <clks/scheduler.h>
#include <clks/string.h>
#include <clks/types.h>
#define CLKS_SCHED_MAX_TASKS 16U
#define CLKS_SCHED_MIN_SLICE 1U
static struct clks_task_descriptor clks_tasks[CLKS_SCHED_MAX_TASKS];
static u32 clks_task_count = 0;
static u32 clks_current_task = 0;
static u64 clks_total_timer_ticks = 0;
static u64 clks_context_switch_count = 0;
static void clks_sched_copy_name(char *dst, const char *src) {
u32 i = 0;
while (i < (CLKS_TASK_NAME_MAX - 1U) && src[i] != '\0') {
dst[i] = src[i];
i++;
}
dst[i] = '\0';
}
static u32 clks_sched_next_ready_task(u32 from) {
u32 i;
for (i = 1U; i <= clks_task_count; i++) {
u32 idx = (from + i) % clks_task_count;
if (clks_tasks[idx].state == CLKS_TASK_READY || clks_tasks[idx].state == CLKS_TASK_RUNNING) {
return idx;
}
}
return from;
}
void clks_scheduler_init(void) {
clks_memset(clks_tasks, 0, sizeof(clks_tasks));
clks_task_count = 0;
clks_current_task = 0;
clks_total_timer_ticks = 0;
clks_context_switch_count = 0;
clks_scheduler_add_kernel_task("idle", 1U);
clks_tasks[0].state = CLKS_TASK_RUNNING;
clks_tasks[0].remaining_ticks = clks_tasks[0].time_slice_ticks;
clks_log(CLKS_LOG_INFO, "SCHED", "ROUND-ROBIN ONLINE");
}
clks_bool clks_scheduler_add_kernel_task(const char *name, u32 time_slice_ticks) {
struct clks_task_descriptor *task;
if (name == CLKS_NULL) {
return CLKS_FALSE;
}
if (clks_task_count >= CLKS_SCHED_MAX_TASKS) {
return CLKS_FALSE;
}
if (time_slice_ticks < CLKS_SCHED_MIN_SLICE) {
time_slice_ticks = CLKS_SCHED_MIN_SLICE;
}
task = &clks_tasks[clks_task_count];
task->id = clks_task_count;
clks_sched_copy_name(task->name, name);
task->state = CLKS_TASK_READY;
task->time_slice_ticks = time_slice_ticks;
task->remaining_ticks = time_slice_ticks;
task->total_ticks = 0;
task->switch_count = 0;
clks_task_count++;
return CLKS_TRUE;
}
void clks_scheduler_on_timer_tick(u64 tick) {
struct clks_task_descriptor *current;
if (clks_task_count == 0U) {
return;
}
clks_total_timer_ticks = tick;
current = &clks_tasks[clks_current_task];
if (current->state == CLKS_TASK_RUNNING || current->state == CLKS_TASK_READY) {
current->total_ticks++;
if (current->remaining_ticks > 0U) {
current->remaining_ticks--;
}
}
if (current->remaining_ticks == 0U) {
u32 next = clks_sched_next_ready_task(clks_current_task);
current->remaining_ticks = current->time_slice_ticks;
if (next != clks_current_task) {
if (current->state == CLKS_TASK_RUNNING) {
current->state = CLKS_TASK_READY;
}
clks_current_task = next;
clks_tasks[clks_current_task].state = CLKS_TASK_RUNNING;
clks_tasks[clks_current_task].switch_count++;
clks_tasks[clks_current_task].remaining_ticks = clks_tasks[clks_current_task].time_slice_ticks;
clks_context_switch_count++;
}
}
}
struct clks_scheduler_stats clks_scheduler_get_stats(void) {
struct clks_scheduler_stats stats;
stats.task_count = clks_task_count;
stats.current_task_id = clks_current_task;
stats.total_timer_ticks = clks_total_timer_ticks;
stats.context_switch_count = clks_context_switch_count;
return stats;
}
const struct clks_task_descriptor *clks_scheduler_get_task(u32 task_id) {
if (task_id >= clks_task_count) {
return CLKS_NULL;
}
return &clks_tasks[task_id];
}