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())
This commit is contained in:
parent
1e0c8c5fe7
commit
f83a6ace51
@ -17,4 +17,5 @@ int main()
|
||||
} while ((allocated = malloc(CHUNK)));
|
||||
perror("malloc");
|
||||
printf("Press any key to restart.\n");
|
||||
return 1;
|
||||
}
|
@ -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);
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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"); }
|
||||
|
@ -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);
|
||||
}
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user