Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/process/scheduler.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ void scheduler_remove_task(task_struct_t* task);
// 스케줄러 통계
uint32_t scheduler_get_total_tasks(void);
void scheduler_print_status(void);
void scheduler_reap_terminated_tasks(void);

// ✅ IRQ 기반 스케줄러 핸들러
// 인터럽트 프레임 구조체는 scheduler.c에 정의됨
Expand Down
1 change: 1 addition & 0 deletions include/process/task.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ typedef struct task_struct {
void task_init(void);
task_struct_t* task_create(const char* name, void (*entry_point)(void), uint32_t priority);
void task_destroy(task_struct_t* task);
void task_exit(void) __attribute__((noreturn));
task_struct_t* task_get_current(void);
void task_set_current(task_struct_t* task);
uint32_t task_get_next_pid(void);
Expand Down
9 changes: 8 additions & 1 deletion src/kernel.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ static void hlt_loop(void) {
for(;;) __asm__ __volatile__("hlt");
}

static void kernel_idle_loop(void) {
for (;;) {
scheduler_reap_terminated_tasks();
__asm__ __volatile__("sti; hlt");
}
}

static void console_putu32(uint32_t v) {
char buf[11];
int idx = 0;
Expand Down Expand Up @@ -279,7 +286,7 @@ void kernel_main(uint32_t magic, void* mbinfo) {
console_puts("[SCHEDULER] Output should cycle through 1, 2, and 3.\n");

idt_enable_interrupts();
hlt_loop();
kernel_idle_loop();
}

// Test: Put string
Expand Down
78 changes: 78 additions & 0 deletions src/process/scheduler.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "process/scheduler.h"
#include "process/task.h"
#include "arch/x86/idt.h"
#include "drivers/console/console.h"
#include <stddef.h>

Expand All @@ -16,8 +17,11 @@ struct interrupt_frame {
// 라운드 로빈 큐
static task_struct_t* ready_queue_head = NULL;
static task_struct_t* ready_queue_tail = NULL;
static task_struct_t* terminated_queue_head = NULL;
static task_struct_t* terminated_queue_tail = NULL;
static task_struct_t* current_task = NULL;
static uint32_t total_tasks = 0;
static uint32_t terminated_tasks = 0;
static uint32_t scheduler_ticks = 0;

static void scheduler_enqueue_task(task_struct_t* task) {
Expand Down Expand Up @@ -57,12 +61,56 @@ static task_struct_t* scheduler_dequeue_task(void) {
return task;
}

static void scheduler_enqueue_terminated_task(task_struct_t* task) {
if (!task || task->pid == 0) {
return;
}

task->next = NULL;
task->prev = terminated_queue_tail;

if (terminated_queue_tail) {
terminated_queue_tail->next = task;
} else {
terminated_queue_head = task;
}

terminated_queue_tail = task;
terminated_tasks++;
}

static task_struct_t* scheduler_dequeue_terminated_task(void) {
task_struct_t* task = terminated_queue_head;
if (!task) {
return NULL;
}

terminated_queue_head = task->next;
if (terminated_queue_head) {
terminated_queue_head->prev = NULL;
} else {
terminated_queue_tail = NULL;
}

task->next = NULL;
task->prev = NULL;

if (terminated_tasks > 0) {
terminated_tasks--;
}

return task;
}

void scheduler_init(void) {
console_puts("[SCHEDULER] Initializing round-robin scheduler...\n");

ready_queue_head = NULL;
ready_queue_tail = NULL;
terminated_queue_head = NULL;
terminated_queue_tail = NULL;
total_tasks = 0;
terminated_tasks = 0;
scheduler_ticks = 0;

// 현재 태스크는 커널 태스크
Expand Down Expand Up @@ -154,6 +202,20 @@ uint32_t scheduler_get_total_tasks(void) {
return total_tasks;
}

void scheduler_reap_terminated_tasks(void) {
for (;;) {
idt_disable_interrupts();
task_struct_t* task = scheduler_dequeue_terminated_task();
idt_enable_interrupts();

if (!task) {
return;
}

task_destroy(task);
}
}

void scheduler_print_status(void) {
console_puts("[SCHEDULER] Status:\n");
console_puts(" Total tasks in ready queue: ");
Expand Down Expand Up @@ -207,6 +269,20 @@ void scheduler_print_status(void) {
while (idx--) console_putc(buf[idx]);
}
console_puts("\n");

console_puts(" Terminated tasks pending cleanup: ");
count = terminated_tasks;
idx = 0;
if (count == 0) {
console_putc('0');
} else {
while (count > 0 && idx < 11) {
buf[idx++] = (char)('0' + (count % 10));
count /= 10;
}
while (idx--) console_putc(buf[idx]);
}
console_puts("\n");

// Ready 큐의 모든 태스크 출력
if (ready_queue_head) {
Expand Down Expand Up @@ -272,6 +348,8 @@ uint32_t scheduler_irq_handler(void* frame_ptr) {
if (old_task->pid != 0) {
scheduler_enqueue_task(old_task);
}
} else if (old_task->state == TASK_TERMINATED) {
scheduler_enqueue_terminated_task(old_task);
}

// 다음 태스크 선택
Expand Down
26 changes: 18 additions & 8 deletions src/process/task.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,7 @@ static void task_entry_trampoline(void) {
current->entry_point();
}

if (current) {
current->state = TASK_TERMINATED;
current->time_remaining = 0;
}

for (;;) {
__asm__ __volatile__("sti; hlt");
}
task_exit();
}

task_struct_t* task_get_kernel_task(void) {
Expand Down Expand Up @@ -70,6 +63,19 @@ uint32_t task_get_next_pid(void) {
return next_pid++;
}

void task_exit(void) {
task_struct_t* current = scheduler_get_current_task();

if (current && current->pid != 0) {
current->state = TASK_TERMINATED;
current->time_remaining = 0;
}

for (;;) {
__asm__ __volatile__("sti; hlt");
}
}

task_struct_t* task_create(const char* name, void (*entry_point)(void), uint32_t priority) {
// PCB 할당
task_struct_t* task = (task_struct_t*)kmalloc(sizeof(task_struct_t));
Expand Down Expand Up @@ -178,6 +184,10 @@ void task_destroy(task_struct_t* task) {
if (!task) {
return;
}

if (task->pid == 0 || task == scheduler_get_current_task()) {
return;
}

console_puts("[TASK] Destroying task PID ");
uint32_t pid = task->pid;
Expand Down