diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/sched.c | 23 | ||||
| -rw-r--r-- | kernel/sys.c | 16 | ||||
| -rw-r--r-- | kernel/timer.s | 4 | ||||
| -rw-r--r-- | kernel/traps.s | 8 |
4 files changed, 43 insertions, 8 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index 529db61..9f955d2 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -199,12 +199,25 @@ void reschedule(void) { n = ctaskn; while(1) { - n = (n + 1) % NRTASKS; - if(tasks[n].pid && tasks[n].state == TSTATE_RUNNING) - break; - } + /* check alarms and signals */ + for(i = 0; i < NRTASKS; i++) { + if(tasks[i].alarm && tasks[i].alarm < ticks) { + tasks[i].alarm = 0; + tasks[i].signal |= 1 << (SIGALRM - 1); + } + if(tasks[i].signal && tasks[i].state == TSTATE_INTERRUPTIBLE) + tasks[i].state = TSTATE_RUNNING; + } - switch_to(n, &tasks[n]); + /* check if a process is ready to run */ + for(i = 0; i < NRTASKS; i++) { + n = (n + 1) % NRTASKS; + if(tasks[n].pid && tasks[n].state == TSTATE_RUNNING) { + switch_to(n, &tasks[n]); + return; + } + } + } } void sched_tick(void) { diff --git a/kernel/sys.c b/kernel/sys.c index 20494de..c2256c1 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -36,12 +36,26 @@ void *sys_signal(int sig, void (*func)(int)) { if(sig == SIGKILL || sig == SIGSTOP) return NULL; - printk("Task %x registered new signal handler 0x%08x for signal %01x\n", ctask->pid, (uint32_t) func, sig); ctask->sig_handlers[sig] = func; return func; } +int sys_alarm(unsigned int seconds) { + if(!seconds) { + ctask->alarm = 0; + return 0; + } + + ctask->alarm = ticks + (seconds * 100); +} + +int sys_pause(void) { + ctask->state = TSTATE_INTERRUPTIBLE; + reschedule(); + return -1; +} + int sys_dummy(void) { return -ENOSYS; } diff --git a/kernel/timer.s b/kernel/timer.s index b96e1f1..6d95281 100644 --- a/kernel/timer.s +++ b/kernel/timer.s @@ -19,6 +19,8 @@ tick_handler: mov es, ax mov fs, ax mov gs, ax + ; save a pointer to the state information + mov ebx, esp ; handle the timer tick mov dword [ticked], 1 inc dword [ticks] @@ -31,7 +33,9 @@ tick_handler: ; if it isn't, call the scheduler call sched_tick ; handle any pending signals before returning to normal execution + push ebx call check_signals + add esp, 4 .end: ; restore the data segment selectors pop ax diff --git a/kernel/traps.s b/kernel/traps.s index 36b3423..0a0d202 100644 --- a/kernel/traps.s +++ b/kernel/traps.s @@ -21,8 +21,8 @@ extern ticked ; too. %define ts_signal 6 -%define ts_sig_handlers 10 -%define ts_tss_esp0 142 +%define ts_sig_handlers 14 +%define ts_tss_esp0 146 %macro SAVE 0 pusha @@ -323,6 +323,7 @@ check_signals: shl ebx, cl xor ebx, 0xFFFFFFFF and dword [eax+ts_signal], ebx + inc ecx mov ebx, ecx ; calculate offset to the handler function shl ecx, 2 @@ -374,7 +375,10 @@ check_signals: ret sigret: + mov ebx, esp + push ebx call check_signals + add esp, 4 ; restore our original stack frame and reset the TSS's ESP0 mov esp, [eax+ts_tss_esp0] mov dword [eax+ts_tss_esp0], 0xFFFFFFFF |
