diff --git a/apps/src/memeater.c b/apps/src/memeater.c index a1c26c71..1fb24091 100644 --- a/apps/src/memeater.c +++ b/apps/src/memeater.c @@ -17,4 +17,5 @@ int main() } while ((allocated = malloc(CHUNK))); perror("malloc"); printf("Press any key to restart.\n"); + return 1; } \ No newline at end of file diff --git a/kernel/include/sys/Syscall.h b/kernel/include/sys/Syscall.h index 295e89fb..e9564a53 100644 --- a/kernel/include/sys/Syscall.h +++ b/kernel/include/sys/Syscall.h @@ -18,7 +18,7 @@ namespace Syscall void entry(Context* context); } -void sys_exit(Context* context); +void sys_exit(Context* context, int status); void sys_yield(Context* context); void sys_sleep(Context* context, uint64_t ms); void sys_write(Context* context, const char* addr, size_t size); diff --git a/kernel/include/thread/Scheduler.h b/kernel/include/thread/Scheduler.h index e6b81a28..3ccf8912 100644 --- a/kernel/include/thread/Scheduler.h +++ b/kernel/include/thread/Scheduler.h @@ -5,15 +5,15 @@ namespace Scheduler { void init(); void yield(); - void exit(); + void exit(int status); void sleep(unsigned long ms); void add_kernel_task(void (*task)(void)); void add_user_task(void* task); void load_user_task(const char* filename); - void task_exit(Context* context); - void task_misbehave(Context* context); + void task_exit(Context* context, int64_t status); + void task_misbehave(Context* context, int64_t status); Task* current_task(); diff --git a/kernel/include/thread/Task.h b/kernel/include/thread/Task.h index 3fb993d5..4803d275 100644 --- a/kernel/include/thread/Task.h +++ b/kernel/include/thread/Task.h @@ -16,6 +16,9 @@ struct Task Context regs; int64_t task_sleep = 0; + + int64_t exit_status; + int64_t task_time = 0; Task* next_task = nullptr; diff --git a/kernel/src/interrupts/Entry.cpp b/kernel/src/interrupts/Entry.cpp index 1d579474..d0d9883e 100644 --- a/kernel/src/interrupts/Entry.cpp +++ b/kernel/src/interrupts/Entry.cpp @@ -34,7 +34,7 @@ extern "C" void common_handler(Context* context) StackTracer tracer(context->rbp); tracer.trace_with_ip(context->rip); - Scheduler::task_misbehave(context); + Scheduler::task_misbehave(context, -2); } } if (context->number == 14) @@ -51,7 +51,7 @@ extern "C" void common_handler(Context* context) StackTracer tracer(context->rbp); tracer.trace_with_ip(context->rip); - Scheduler::task_misbehave(context); + Scheduler::task_misbehave(context, -3); } } if (context->number == 8) { int_panic(context, "Double fault, halting"); } diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index fde65f46..4b5c71b9 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -163,5 +163,5 @@ extern "C" void _start() kinfoln("Found PCI device %x:%x, %s", dev.id().vendor, dev.id().device, pci_type_name(dev.type())); }); - Scheduler::exit(); + Scheduler::exit(0); } \ No newline at end of file diff --git a/kernel/src/sys/Syscall.cpp b/kernel/src/sys/Syscall.cpp index 26785759..70111a09 100644 --- a/kernel/src/sys/Syscall.cpp +++ b/kernel/src/sys/Syscall.cpp @@ -9,7 +9,7 @@ void Syscall::entry(Context* context) switch (context->rax) { case SYS_exit: // sys_exit - sys_exit(context); + sys_exit(context, (int)context->rdi); break; case SYS_yield: // sys_yield sys_yield(context); diff --git a/kernel/src/sys/sched.cpp b/kernel/src/sys/sched.cpp index 3681d520..952ead52 100644 --- a/kernel/src/sys/sched.cpp +++ b/kernel/src/sys/sched.cpp @@ -1,8 +1,8 @@ #include "thread/Scheduler.h" -void sys_exit(Context* context) +void sys_exit(Context* context, int status) { - Scheduler::task_exit(context); + Scheduler::task_exit(context, status); } void sys_yield(Context* context) diff --git a/kernel/src/thread/Scheduler.cpp b/kernel/src/thread/Scheduler.cpp index 9978cefc..62b090ef 100644 --- a/kernel/src/thread/Scheduler.cpp +++ b/kernel/src/thread/Scheduler.cpp @@ -153,7 +153,7 @@ void Scheduler::reap_task(Task* task) task_num--; Task* exiting_task = task; ASSERT(task->id != 0); // WHY IN THE WORLD WOULD WE BE REAPING THE IDLE TASK? - kinfoln("reaping task %ld", exiting_task->id); + kinfoln("reaping task %ld, exited with code %ld", exiting_task->id, exiting_task->exit_status); if (exiting_task->allocated_stack) MemoryManager::release_pages((void*)exiting_task->allocated_stack, TASK_PAGES_IN_STACK); if (exiting_task->image) @@ -168,20 +168,22 @@ void Scheduler::reap_task(Task* task) delete exiting_task; } -void Scheduler::task_exit(Context* context) +void Scheduler::task_exit(Context* context, int64_t status) { ASSERT(Interrupts::is_in_handler()); kdbgln("exit: task %ld finished running, used %ld ms of cpu time", sched_current_task->id, sched_current_task->cpu_time); sched_current_task->state = sched_current_task->Exited; + sched_current_task->exit_status = status; task_yield(context); } -void Scheduler::task_misbehave(Context* context) +void Scheduler::task_misbehave(Context* context, int64_t status) { ASSERT(Interrupts::is_in_handler()); kdbgln("exit: task %ld misbehaved, used %ld ms of cpu time", sched_current_task->id, sched_current_task->cpu_time); sched_current_task->state = sched_current_task->Exited; + sched_current_task->exit_status = status; task_yield(context); } @@ -311,9 +313,9 @@ void Scheduler::yield() asm volatile("int $0x42" : : "a"(1)); } -void Scheduler::exit() +void Scheduler::exit(int status) { - asm volatile("int $0x42" : : "a"(0)); + asm volatile("int $0x42" : : "a"(0), "D"(status)); } void Scheduler::sleep(unsigned long ms) diff --git a/libs/libc/src/stdlib.cpp b/libs/libc/src/stdlib.cpp index bae18830..427c6ec7 100644 --- a/libs/libc/src/stdlib.cpp +++ b/libs/libc/src/stdlib.cpp @@ -15,9 +15,9 @@ extern "C" exit(-1); } - noreturn void exit(int) + noreturn void exit(int status) { - syscall(SYS_exit); + syscall(SYS_exit, status); __builtin_unreachable(); } diff --git a/libs/libc/src/unistd.cpp b/libs/libc/src/unistd.cpp index 84ae01d3..783c39b8 100644 --- a/libs/libc/src/unistd.cpp +++ b/libs/libc/src/unistd.cpp @@ -31,10 +31,10 @@ extern "C" va_start(ap, number); switch (number) { - case SYS_exit: case SYS_yield: case SYS_gettid: case SYS_rand: result = __luna_syscall0(number); break; + case SYS_exit: case SYS_sleep: result = __luna_syscall1(number, va_arg(ap, arg)); break; case SYS_write: case SYS_munmap: