Compare commits

...

2 Commits

Author SHA1 Message Date
247645d301 Merge branch exit_status into main
Reviewed-on: #8
2022-10-08 15:58:51 +00:00
f83a6ace51 Kernel, libc: Add support for providing a status code to exit()
The exit() libc function already accepted an integer, but didn't pass it on to the kernel since we had no mechanism for it to do that.
Now, the kernel stores a task's exit status to display it later (and in the future, return it to userspace via wait()/waitpid())
2022-10-08 17:56:40 +02:00
11 changed files with 24 additions and 18 deletions

View File

@ -17,4 +17,5 @@ int main()
} while ((allocated = malloc(CHUNK)));
perror("malloc");
printf("Press any key to restart.\n");
return 1;
}

View File

@ -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);

View File

@ -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();

View File

@ -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;

View File

@ -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"); }

View File

@ -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);
}

View File

@ -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);

View File

@ -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)

View File

@ -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)

View File

@ -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();
}

View File

@ -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: