Skip to content
This repository was archived by the owner on Jan 14, 2026. It is now read-only.

Commit 7b9f459

Browse files
committed
add simple prenptive multi task :D
1 parent 1957c67 commit 7b9f459

7 files changed

Lines changed: 105 additions & 33 deletions

File tree

src/kernel/fs/vfs.c

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -178,23 +178,17 @@ void vfs_register_builtin_backends(void) {
178178
int vfs_mount_with_cache(struct block_cache *cache) {
179179
if (!cache)
180180
return -1;
181-
printk("vfs: attempting to mount %d registered backends\n",
182-
backend_count);
181+
183182
for (int i = 0; i < backend_count; ++i) {
184183
void *sb = NULL;
185184
if (!backends[i])
186185
continue;
187-
printk("vfs: trying backend %s\n", backends[i]->name);
188186
int r = -1;
189187
if (backends[i]->mount_with_cache)
190188
r = backends[i]->mount_with_cache(cache, &sb);
191-
printk("vfs: backend %s mount result %d\n", backends[i]->name,
192-
r);
193189
if (r == 0) {
194190
active_backend = backends[i];
195191
active_sb = sb;
196-
printk("vfs: mounted backend %s\n",
197-
active_backend->name);
198192
return 0;
199193
}
200194
}

src/kernel/interrupt/irq_preempt.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <driver/timer/apic.h>
44
#include <util/console.h>
55
#include <stdint.h>
6+
#include "irq_trace.h"
67

78
// スタックレイアウト (regs_stack のインデックス):
89
// 0: RAX
@@ -50,15 +51,16 @@ void irq_preempt_entry(uint64_t *regs_stack, uint32_t vec) {
5051
t->regs.rip = regs_stack[15];
5152
t->regs.rflags = regs_stack[17];
5253

53-
// RSP は RIP が置かれているスタック位置へのポインタとする
54-
t->regs.rsp = (uint64_t)(&regs_stack[15]);
54+
t->regs.rsp = (uint64_t)(&regs_stack[15]) + 8;
5555

5656
// CR3 を読み取って保存
5757
uint64_t cr3;
5858
asm volatile("mov %%cr3, %0" : "=r"(cr3));
5959
t->regs.cr3 = cr3;
6060
}
6161

62+
irq_trace_record_from_stack(regs_stack, vec);
63+
6264
// タイマ割り込みベクタならタイマーハンドラを即時実行
6365
if (vec == 48) {
6466
// APIC タイマの同期処理
@@ -70,4 +72,4 @@ void irq_preempt_entry(uint64_t *regs_stack, uint32_t vec) {
7072
if (t) {
7173
task_schedule_from_irq(&t->regs);
7274
}
73-
}
75+
}

src/kernel/interrupt/irq_timer.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <task/multi_task.h>
44
#include <driver/timer/apic.h>
55
#include <stdint.h>
6+
#include "irq_trace.h"
67

78
// IRQ 経路から呼ばれるスケジューラ関数(TCB のレジスタポインタを渡す)
89
extern void task_schedule_from_irq(registers_t *irq_regs);
@@ -36,15 +37,20 @@ void irq_timer_entry(uint64_t *regs_stack) {
3637
t->regs.rip = regs_stack[15];
3738
t->regs.rflags = regs_stack[17];
3839

39-
uintptr_t saved_rsp =
40-
(uintptr_t)regs_stack + (size_t)((15 + 3) * 8);
41-
t->regs.rsp = saved_rsp;
40+
/* RSP は RIP が置かれているスタック位置へのポインタとする
41+
* task_switch/task_restore が期待する形式に合わせて +8 を行う
42+
*/
43+
t->regs.rsp = (uint64_t)(&regs_stack[15]) + 8;
4244

4345
// CR3 は現在の CR3 を読み取って保存
4446
uint64_t cr3val;
4547
asm volatile("mov %%cr3, %0" : "=r"(cr3val));
4648
t->regs.cr3 = cr3val;
4749
}
4850

49-
task_schedule_from_irq(&t->regs);
51+
irq_trace_record_from_stack(regs_stack, 48);
52+
53+
if (t) {
54+
task_schedule_from_irq(&t->regs);
55+
}
5056
}

src/kernel/interrupt/irq_trace.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#include "irq_trace.h"
2+
#include <task/multi_task.h>
3+
#include <stdint.h>
4+
#include <util/console.h>
5+
6+
static irq_trace_entry_t irq_trace_buf[IRQ_TRACE_CAPACITY];
7+
static volatile unsigned irq_trace_head = 0; // next write index
8+
9+
// IRQ-safe minimal record: no allocation, no printk
10+
void irq_trace_record(uint64_t vec, uint64_t rip, uint64_t rsp, uint64_t cr3,
11+
uint64_t rflags, uint32_t tid) {
12+
unsigned idx = irq_trace_head++;
13+
idx &= (IRQ_TRACE_CAPACITY - 1);
14+
irq_trace_buf[idx].vec = vec;
15+
irq_trace_buf[idx].rip = rip;
16+
irq_trace_buf[idx].rsp = rsp;
17+
irq_trace_buf[idx].cr3 = cr3;
18+
irq_trace_buf[idx].rflags = rflags;
19+
irq_trace_buf[idx].tid = tid;
20+
}
21+
22+
// regs_stack layout assumed by irq stubs: see irq_stubs.asm
23+
// index 15 = RIP, index 17 = RFLAGS. RSP we record as pointer-based value
24+
void irq_trace_record_from_stack(uint64_t *regs_stack, uint32_t vec) {
25+
uint64_t rip = regs_stack[15];
26+
uint64_t rflags = regs_stack[17];
27+
// saved RSP pointer: caller's code in IRQ handler will expect saved RSP
28+
uint64_t rsp_ptr = (uint64_t)(&regs_stack[15]);
29+
30+
uint64_t cr3_val = 0;
31+
asm volatile("mov %%cr3, %0" : "=r"(cr3_val));
32+
33+
uint32_t tid = 0;
34+
task_t *t = task_current();
35+
if (t)
36+
tid = t->tid;
37+
38+
irq_trace_record(vec, rip, rsp_ptr, cr3_val, rflags, tid);
39+
}
40+
41+
// Dump the buffer using printk — call only from non-IRQ context
42+
void irq_trace_dump(void) {
43+
printk("--- IRQ trace dump (last %d entries) ---\n",
44+
IRQ_TRACE_CAPACITY);
45+
unsigned start = (irq_trace_head >= IRQ_TRACE_CAPACITY) ?
46+
(irq_trace_head & (IRQ_TRACE_CAPACITY - 1)) :
47+
0;
48+
unsigned count = (irq_trace_head >= IRQ_TRACE_CAPACITY) ?
49+
IRQ_TRACE_CAPACITY :
50+
irq_trace_head;
51+
for (unsigned i = 0; i < count; ++i) {
52+
unsigned idx = (start + i) & (IRQ_TRACE_CAPACITY - 1);
53+
irq_trace_entry_t *e = &irq_trace_buf[idx];
54+
printk("[%3u] vec=%u tid=%u rip=0x%lx rsp=0x%lx cr3=0x%lx rflags=0x%lx\n",
55+
(unsigned)i, (unsigned)e->vec, (unsigned)e->tid,
56+
(unsigned long)e->rip, (unsigned long)e->rsp,
57+
(unsigned long)e->cr3, (unsigned long)e->rflags);
58+
}
59+
}

src/kernel/interrupt/irq_trace.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Minimal IRQ trace buffer for lightweight recording from IRQ context.
2+
#ifndef IRQ_TRACE_H
3+
#define IRQ_TRACE_H
4+
5+
#include <stdint.h>
6+
7+
#define IRQ_TRACE_CAPACITY 1024
8+
9+
typedef struct irq_trace_entry {
10+
uint64_t vec;
11+
uint64_t rip;
12+
uint64_t rsp;
13+
uint64_t cr3;
14+
uint64_t rflags;
15+
uint32_t tid;
16+
} irq_trace_entry_t;
17+
18+
void irq_trace_record(uint64_t vec, uint64_t rip, uint64_t rsp, uint64_t cr3,
19+
uint64_t rflags, uint32_t tid);
20+
void irq_trace_record_from_stack(uint64_t *regs_stack, uint32_t vec);
21+
void irq_trace_dump(void);
22+
23+
#endif // IRQ_TRACE_H

src/kernel/task/multi_task.c

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,12 @@ void task_schedule(void) {
387387

388388
irq_restore(flags);
389389

390+
/* 非 IRQ コンテキストでトレースバッファをダンプ(必要なら) */
391+
extern void irq_trace_dump(void);
392+
if (next_task == &idle_task) {
393+
irq_trace_dump();
394+
}
395+
390396
// コンテキストスイッチ(異なるタスクの場合のみ)
391397
if (old_task != next_task) {
392398
task_switch(&old_task->regs, &next_task->regs);
@@ -401,16 +407,13 @@ void task_exit(void) {
401407

402408
if (current_task) {
403409
current_task->state = TASK_STATE_DEAD;
404-
printk("task_exit: Task '%s' (TID=%u) exited\n",
405-
current_task->name, (unsigned)current_task->tid);
406410
}
407411

408412
irq_restore(flags);
409413

410414
// スケジューラを呼んで次のタスクへ
411415
task_schedule();
412416

413-
// ここには戻ってこない
414417
while (1) {
415418
asm volatile("hlt");
416419
}
@@ -432,8 +435,6 @@ void task_schedule_from_irq(registers_t *irq_regs) {
432435
if (!scheduler_enabled || !current_task)
433436
return;
434437

435-
/* IRQ コンテキストでは既に割り込みは無効化されているはず */
436-
437438
task_t *next_task = NULL;
438439

439440
/* レディキューから次のタスクを取得 */
@@ -471,13 +472,8 @@ void task_schedule_from_irq(registers_t *irq_regs) {
471472
current_task = next_task;
472473
next_task->state = TASK_STATE_RUNNING;
473474

474-
/* IRQ コンテキストでは既に元のレジスタは TCB に保存済みであるため
475-
* 古いレジスタを再保存する必要はない。直接新しいタスクを復元する。
476-
* irq_regs は呼び元で保存された current_task のレジスタへのポインタ。
477-
*/
478475
if (old_task != next_task) {
479-
(void)irq_regs; /* 今の実装では current_task->regs に保存済みなので未使用 */
476+
(void)irq_regs;
480477
task_restore(&next_task->regs);
481-
/* task_restore は新タスクへ復帰するため通常ここには戻らない */
482478
}
483479
}

src/kernel/task/multi_task.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -97,16 +97,8 @@ void task_yield(void);
9797
*/
9898
extern void task_switch(registers_t *old_regs, registers_t *new_regs);
9999

100-
// IRQ コンテキストから呼ばれるスケジューラヘルパー
101-
// irq_regs: IRQ スタックから保存した現在タスクのレジスタ
102100
void task_schedule_from_irq(registers_t *irq_regs);
103101

104-
// IRQ コンテキストから直接スケジューリングを行う
105-
// この関数は irq_timer_entry 等の IRQ ハンドラから呼ばれる。
106-
// (task_schedule_from_irq は上で定義済み)
107-
108-
// 新しいタスクのレジスタを即時復元して実行する(アセンブリ)
109-
// 引数: rdi = registers_t * (復元対象)
110102
extern void task_restore(registers_t *new_regs);
111103

112104
#endif /* _TASK_TASK_H */

0 commit comments

Comments
 (0)