mirror of
https://github.com/Leonmmcoset/cleonos.git
synced 2026-04-21 18:44:01 +00:00
Stage 9
This commit is contained in:
@@ -11,11 +11,46 @@
|
||||
#include <clks/pmm.h>
|
||||
#include <clks/scheduler.h>
|
||||
#include <clks/serial.h>
|
||||
#include <clks/service.h>
|
||||
#include <clks/syscall.h>
|
||||
#include <clks/tty.h>
|
||||
#include <clks/types.h>
|
||||
#include <clks/userland.h>
|
||||
|
||||
static void clks_task_klogd(u64 tick) {
|
||||
static u64 last_emit = 0ULL;
|
||||
|
||||
clks_service_heartbeat(CLKS_SERVICE_LOG, tick);
|
||||
|
||||
if (tick - last_emit >= 1000ULL) {
|
||||
clks_log_hex(CLKS_LOG_DEBUG, "TASK", "KLOGD_TICK", tick);
|
||||
last_emit = tick;
|
||||
}
|
||||
}
|
||||
|
||||
static void clks_task_kworker(u64 tick) {
|
||||
static u32 phase = 0U;
|
||||
|
||||
clks_service_heartbeat(CLKS_SERVICE_SCHED, tick);
|
||||
|
||||
switch (phase) {
|
||||
case 0U:
|
||||
clks_service_heartbeat(CLKS_SERVICE_MEM, tick);
|
||||
break;
|
||||
case 1U:
|
||||
clks_service_heartbeat(CLKS_SERVICE_FS, tick);
|
||||
break;
|
||||
case 2U:
|
||||
clks_service_heartbeat(CLKS_SERVICE_DRIVER, tick);
|
||||
break;
|
||||
default:
|
||||
clks_service_heartbeat(CLKS_SERVICE_LOG, tick);
|
||||
break;
|
||||
}
|
||||
|
||||
phase = (phase + 1U) & 3U;
|
||||
}
|
||||
|
||||
void clks_kernel_main(void) {
|
||||
const struct limine_framebuffer *boot_fb;
|
||||
const struct limine_memmap_response *boot_memmap;
|
||||
@@ -41,7 +76,7 @@ void clks_kernel_main(void) {
|
||||
clks_tty_init();
|
||||
}
|
||||
|
||||
clks_log(CLKS_LOG_INFO, "BOOT", "CLEONOS STAGE8 START");
|
||||
clks_log(CLKS_LOG_INFO, "BOOT", "CLEONOS STAGE9 START");
|
||||
|
||||
if (boot_fb == CLKS_NULL) {
|
||||
clks_log(CLKS_LOG_WARN, "VIDEO", "NO FRAMEBUFFER FROM LIMINE");
|
||||
@@ -112,17 +147,19 @@ void clks_kernel_main(void) {
|
||||
|
||||
clks_scheduler_init();
|
||||
|
||||
if (clks_scheduler_add_kernel_task("klogd", 4U) == CLKS_FALSE) {
|
||||
if (clks_scheduler_add_kernel_task_ex("klogd", 4U, clks_task_klogd) == CLKS_FALSE) {
|
||||
clks_log(CLKS_LOG_WARN, "SCHED", "FAILED TO ADD KLOGD TASK");
|
||||
}
|
||||
|
||||
if (clks_scheduler_add_kernel_task("kworker", 3U) == CLKS_FALSE) {
|
||||
if (clks_scheduler_add_kernel_task_ex("kworker", 3U, clks_task_kworker) == 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_service_init();
|
||||
|
||||
clks_elfrunner_init();
|
||||
|
||||
if (clks_elfrunner_probe_kernel_executable() == CLKS_FALSE) {
|
||||
|
||||
@@ -44,7 +44,7 @@ void clks_scheduler_init(void) {
|
||||
clks_total_timer_ticks = 0;
|
||||
clks_context_switch_count = 0;
|
||||
|
||||
clks_scheduler_add_kernel_task("idle", 1U);
|
||||
clks_scheduler_add_kernel_task_ex("idle", 1U, CLKS_NULL);
|
||||
|
||||
clks_tasks[0].state = CLKS_TASK_RUNNING;
|
||||
clks_tasks[0].remaining_ticks = clks_tasks[0].time_slice_ticks;
|
||||
@@ -52,7 +52,7 @@ void clks_scheduler_init(void) {
|
||||
clks_log(CLKS_LOG_INFO, "SCHED", "ROUND-ROBIN ONLINE");
|
||||
}
|
||||
|
||||
clks_bool clks_scheduler_add_kernel_task(const char *name, u32 time_slice_ticks) {
|
||||
clks_bool clks_scheduler_add_kernel_task_ex(const char *name, u32 time_slice_ticks, clks_task_entry_fn entry) {
|
||||
struct clks_task_descriptor *task;
|
||||
|
||||
if (name == CLKS_NULL) {
|
||||
@@ -73,13 +73,42 @@ clks_bool clks_scheduler_add_kernel_task(const char *name, u32 time_slice_ticks)
|
||||
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;
|
||||
task->total_ticks = 0ULL;
|
||||
task->switch_count = 0ULL;
|
||||
task->run_count = 0ULL;
|
||||
task->last_run_tick = 0ULL;
|
||||
task->entry = entry;
|
||||
|
||||
clks_task_count++;
|
||||
return CLKS_TRUE;
|
||||
}
|
||||
|
||||
clks_bool clks_scheduler_add_kernel_task(const char *name, u32 time_slice_ticks) {
|
||||
return clks_scheduler_add_kernel_task_ex(name, time_slice_ticks, CLKS_NULL);
|
||||
}
|
||||
|
||||
void clks_scheduler_dispatch_current(u64 tick) {
|
||||
struct clks_task_descriptor *current;
|
||||
|
||||
if (clks_task_count == 0U) {
|
||||
return;
|
||||
}
|
||||
|
||||
current = &clks_tasks[clks_current_task];
|
||||
|
||||
if (current->state != CLKS_TASK_RUNNING && current->state != CLKS_TASK_READY) {
|
||||
return;
|
||||
}
|
||||
|
||||
current->state = CLKS_TASK_RUNNING;
|
||||
current->run_count++;
|
||||
current->last_run_tick = tick;
|
||||
|
||||
if (current->entry != CLKS_NULL) {
|
||||
current->entry(tick);
|
||||
}
|
||||
}
|
||||
|
||||
void clks_scheduler_on_timer_tick(u64 tick) {
|
||||
struct clks_task_descriptor *current;
|
||||
|
||||
@@ -88,7 +117,6 @@ void clks_scheduler_on_timer_tick(u64 tick) {
|
||||
}
|
||||
|
||||
clks_total_timer_ticks = tick;
|
||||
|
||||
current = &clks_tasks[clks_current_task];
|
||||
|
||||
if (current->state == CLKS_TASK_RUNNING || current->state == CLKS_TASK_READY) {
|
||||
@@ -116,6 +144,8 @@ void clks_scheduler_on_timer_tick(u64 tick) {
|
||||
clks_context_switch_count++;
|
||||
}
|
||||
}
|
||||
|
||||
clks_scheduler_dispatch_current(tick);
|
||||
}
|
||||
|
||||
struct clks_scheduler_stats clks_scheduler_get_stats(void) {
|
||||
@@ -135,4 +165,4 @@ const struct clks_task_descriptor *clks_scheduler_get_task(u32 task_id) {
|
||||
}
|
||||
|
||||
return &clks_tasks[task_id];
|
||||
}
|
||||
}
|
||||
|
||||
138
clks/kernel/service.c
Normal file
138
clks/kernel/service.c
Normal file
@@ -0,0 +1,138 @@
|
||||
#include <clks/driver.h>
|
||||
#include <clks/fs.h>
|
||||
#include <clks/heap.h>
|
||||
#include <clks/log.h>
|
||||
#include <clks/scheduler.h>
|
||||
#include <clks/service.h>
|
||||
#include <clks/string.h>
|
||||
#include <clks/types.h>
|
||||
|
||||
#define CLKS_SERVICE_MAX 8U
|
||||
|
||||
static struct clks_service_info clks_services[CLKS_SERVICE_MAX];
|
||||
static u64 clks_service_used = 0ULL;
|
||||
|
||||
static void clks_service_copy_name(char *dst, usize dst_size, const char *src) {
|
||||
usize i = 0U;
|
||||
|
||||
if (dst == CLKS_NULL || dst_size == 0U) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (i + 1U < dst_size && src[i] != '\0') {
|
||||
dst[i] = src[i];
|
||||
i++;
|
||||
}
|
||||
|
||||
dst[i] = '\0';
|
||||
}
|
||||
|
||||
static i32 clks_service_find_index(u32 service_id) {
|
||||
u64 i;
|
||||
|
||||
for (i = 0ULL; i < clks_service_used; i++) {
|
||||
if (clks_services[i].id == service_id) {
|
||||
return (i32)i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static clks_bool clks_service_register(u32 id, const char *name, enum clks_service_state state) {
|
||||
struct clks_service_info *slot;
|
||||
|
||||
if (clks_service_used >= CLKS_SERVICE_MAX) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
slot = &clks_services[clks_service_used];
|
||||
clks_memset(slot, 0, sizeof(*slot));
|
||||
|
||||
slot->id = id;
|
||||
clks_service_copy_name(slot->name, sizeof(slot->name), name);
|
||||
slot->state = state;
|
||||
slot->heartbeat_count = 0ULL;
|
||||
slot->last_heartbeat_tick = 0ULL;
|
||||
|
||||
clks_service_used++;
|
||||
return CLKS_TRUE;
|
||||
}
|
||||
|
||||
void clks_service_init(void) {
|
||||
struct clks_heap_stats heap_stats;
|
||||
|
||||
clks_memset(clks_services, 0, sizeof(clks_services));
|
||||
clks_service_used = 0ULL;
|
||||
|
||||
heap_stats = clks_heap_get_stats();
|
||||
|
||||
clks_service_register(CLKS_SERVICE_LOG, "log", CLKS_SERVICE_STATE_READY);
|
||||
clks_service_register(CLKS_SERVICE_MEM,
|
||||
"memory",
|
||||
(heap_stats.total_bytes > 0U) ? CLKS_SERVICE_STATE_READY : CLKS_SERVICE_STATE_DEGRADED);
|
||||
clks_service_register(CLKS_SERVICE_FS,
|
||||
"filesystem",
|
||||
(clks_fs_is_ready() == CLKS_TRUE) ? CLKS_SERVICE_STATE_READY : CLKS_SERVICE_STATE_DEGRADED);
|
||||
clks_service_register(CLKS_SERVICE_DRIVER,
|
||||
"driver",
|
||||
(clks_driver_count() > 0ULL) ? CLKS_SERVICE_STATE_READY : CLKS_SERVICE_STATE_DEGRADED);
|
||||
clks_service_register(CLKS_SERVICE_SCHED,
|
||||
"scheduler",
|
||||
CLKS_SERVICE_STATE_READY);
|
||||
|
||||
clks_log(CLKS_LOG_INFO, "SRV", "KERNEL SERVICES ONLINE");
|
||||
clks_log_hex(CLKS_LOG_INFO, "SRV", "COUNT", clks_service_count());
|
||||
clks_log_hex(CLKS_LOG_INFO, "SRV", "READY", clks_service_ready_count());
|
||||
}
|
||||
|
||||
clks_bool clks_service_heartbeat(u32 service_id, u64 tick) {
|
||||
i32 idx = clks_service_find_index(service_id);
|
||||
|
||||
if (idx < 0) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
clks_services[(u32)idx].heartbeat_count++;
|
||||
clks_services[(u32)idx].last_heartbeat_tick = tick;
|
||||
|
||||
if (clks_services[(u32)idx].state == CLKS_SERVICE_STATE_OFFLINE) {
|
||||
clks_services[(u32)idx].state = CLKS_SERVICE_STATE_READY;
|
||||
}
|
||||
|
||||
return CLKS_TRUE;
|
||||
}
|
||||
|
||||
u64 clks_service_count(void) {
|
||||
return clks_service_used;
|
||||
}
|
||||
|
||||
u64 clks_service_ready_count(void) {
|
||||
u64 i;
|
||||
u64 ready = 0ULL;
|
||||
|
||||
for (i = 0ULL; i < clks_service_used; i++) {
|
||||
if (clks_services[i].state == CLKS_SERVICE_STATE_READY) {
|
||||
ready++;
|
||||
}
|
||||
}
|
||||
|
||||
return ready;
|
||||
}
|
||||
|
||||
clks_bool clks_service_get(u32 service_id, struct clks_service_info *out_info) {
|
||||
i32 idx;
|
||||
|
||||
if (out_info == CLKS_NULL) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
idx = clks_service_find_index(service_id);
|
||||
|
||||
if (idx < 0) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
*out_info = clks_services[(u32)idx];
|
||||
return CLKS_TRUE;
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <clks/interrupts.h>
|
||||
#include <clks/log.h>
|
||||
#include <clks/scheduler.h>
|
||||
#include <clks/service.h>
|
||||
#include <clks/syscall.h>
|
||||
#include <clks/types.h>
|
||||
|
||||
@@ -83,6 +84,14 @@ u64 clks_syscall_dispatch(void *frame_ptr) {
|
||||
struct clks_scheduler_stats stats = clks_scheduler_get_stats();
|
||||
return stats.current_task_id;
|
||||
}
|
||||
case CLKS_SYSCALL_SERVICE_COUNT:
|
||||
return clks_service_count();
|
||||
case CLKS_SYSCALL_SERVICE_READY_COUNT:
|
||||
return clks_service_ready_count();
|
||||
case CLKS_SYSCALL_CONTEXT_SWITCHES: {
|
||||
struct clks_scheduler_stats stats = clks_scheduler_get_stats();
|
||||
return stats.context_switch_count;
|
||||
}
|
||||
default:
|
||||
return (u64)-1;
|
||||
}
|
||||
@@ -99,4 +108,4 @@ u64 clks_syscall_invoke_kernel(u64 id, u64 arg0, u64 arg1, u64 arg2) {
|
||||
);
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user