commit
247645d301
@ -17,4 +17,5 @@ int main()
|
|||||||
} while ((allocated = malloc(CHUNK)));
|
} while ((allocated = malloc(CHUNK)));
|
||||||
perror("malloc");
|
perror("malloc");
|
||||||
printf("Press any key to restart.\n");
|
printf("Press any key to restart.\n");
|
||||||
|
return 1;
|
||||||
}
|
}
|
@ -18,7 +18,7 @@ namespace Syscall
|
|||||||
void entry(Context* context);
|
void entry(Context* context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sys_exit(Context* context);
|
void sys_exit(Context* context, int status);
|
||||||
void sys_yield(Context* context);
|
void sys_yield(Context* context);
|
||||||
void sys_sleep(Context* context, uint64_t ms);
|
void sys_sleep(Context* context, uint64_t ms);
|
||||||
void sys_write(Context* context, const char* addr, size_t size);
|
void sys_write(Context* context, const char* addr, size_t size);
|
||||||
|
@ -5,15 +5,15 @@ namespace Scheduler
|
|||||||
{
|
{
|
||||||
void init();
|
void init();
|
||||||
void yield();
|
void yield();
|
||||||
void exit();
|
void exit(int status);
|
||||||
void sleep(unsigned long ms);
|
void sleep(unsigned long ms);
|
||||||
void add_kernel_task(void (*task)(void));
|
void add_kernel_task(void (*task)(void));
|
||||||
void add_user_task(void* task);
|
void add_user_task(void* task);
|
||||||
|
|
||||||
void load_user_task(const char* filename);
|
void load_user_task(const char* filename);
|
||||||
|
|
||||||
void task_exit(Context* context);
|
void task_exit(Context* context, int64_t status);
|
||||||
void task_misbehave(Context* context);
|
void task_misbehave(Context* context, int64_t status);
|
||||||
|
|
||||||
Task* current_task();
|
Task* current_task();
|
||||||
|
|
||||||
|
@ -16,6 +16,9 @@ struct Task
|
|||||||
Context regs;
|
Context regs;
|
||||||
|
|
||||||
int64_t task_sleep = 0;
|
int64_t task_sleep = 0;
|
||||||
|
|
||||||
|
int64_t exit_status;
|
||||||
|
|
||||||
int64_t task_time = 0;
|
int64_t task_time = 0;
|
||||||
|
|
||||||
Task* next_task = nullptr;
|
Task* next_task = nullptr;
|
||||||
|
@ -34,7 +34,7 @@ extern "C" void common_handler(Context* context)
|
|||||||
|
|
||||||
StackTracer tracer(context->rbp);
|
StackTracer tracer(context->rbp);
|
||||||
tracer.trace_with_ip(context->rip);
|
tracer.trace_with_ip(context->rip);
|
||||||
Scheduler::task_misbehave(context);
|
Scheduler::task_misbehave(context, -2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (context->number == 14)
|
if (context->number == 14)
|
||||||
@ -51,7 +51,7 @@ extern "C" void common_handler(Context* context)
|
|||||||
StackTracer tracer(context->rbp);
|
StackTracer tracer(context->rbp);
|
||||||
tracer.trace_with_ip(context->rip);
|
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"); }
|
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()));
|
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)
|
switch (context->rax)
|
||||||
{
|
{
|
||||||
case SYS_exit: // sys_exit
|
case SYS_exit: // sys_exit
|
||||||
sys_exit(context);
|
sys_exit(context, (int)context->rdi);
|
||||||
break;
|
break;
|
||||||
case SYS_yield: // sys_yield
|
case SYS_yield: // sys_yield
|
||||||
sys_yield(context);
|
sys_yield(context);
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#include "thread/Scheduler.h"
|
#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)
|
void sys_yield(Context* context)
|
||||||
|
@ -153,7 +153,7 @@ void Scheduler::reap_task(Task* task)
|
|||||||
task_num--;
|
task_num--;
|
||||||
Task* exiting_task = task;
|
Task* exiting_task = task;
|
||||||
ASSERT(task->id != 0); // WHY IN THE WORLD WOULD WE BE REAPING THE IDLE 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)
|
if (exiting_task->allocated_stack)
|
||||||
MemoryManager::release_pages((void*)exiting_task->allocated_stack, TASK_PAGES_IN_STACK);
|
MemoryManager::release_pages((void*)exiting_task->allocated_stack, TASK_PAGES_IN_STACK);
|
||||||
if (exiting_task->image)
|
if (exiting_task->image)
|
||||||
@ -168,20 +168,22 @@ void Scheduler::reap_task(Task* task)
|
|||||||
delete exiting_task;
|
delete exiting_task;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scheduler::task_exit(Context* context)
|
void Scheduler::task_exit(Context* context, int64_t status)
|
||||||
{
|
{
|
||||||
ASSERT(Interrupts::is_in_handler());
|
ASSERT(Interrupts::is_in_handler());
|
||||||
kdbgln("exit: task %ld finished running, used %ld ms of cpu time", sched_current_task->id,
|
kdbgln("exit: task %ld finished running, used %ld ms of cpu time", sched_current_task->id,
|
||||||
sched_current_task->cpu_time);
|
sched_current_task->cpu_time);
|
||||||
sched_current_task->state = sched_current_task->Exited;
|
sched_current_task->state = sched_current_task->Exited;
|
||||||
|
sched_current_task->exit_status = status;
|
||||||
task_yield(context);
|
task_yield(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scheduler::task_misbehave(Context* context)
|
void Scheduler::task_misbehave(Context* context, int64_t status)
|
||||||
{
|
{
|
||||||
ASSERT(Interrupts::is_in_handler());
|
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);
|
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->state = sched_current_task->Exited;
|
||||||
|
sched_current_task->exit_status = status;
|
||||||
task_yield(context);
|
task_yield(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,9 +313,9 @@ void Scheduler::yield()
|
|||||||
asm volatile("int $0x42" : : "a"(1));
|
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)
|
void Scheduler::sleep(unsigned long ms)
|
||||||
|
@ -15,9 +15,9 @@ extern "C"
|
|||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
noreturn void exit(int)
|
noreturn void exit(int status)
|
||||||
{
|
{
|
||||||
syscall(SYS_exit);
|
syscall(SYS_exit, status);
|
||||||
__builtin_unreachable();
|
__builtin_unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,10 +31,10 @@ extern "C"
|
|||||||
va_start(ap, number);
|
va_start(ap, number);
|
||||||
switch (number)
|
switch (number)
|
||||||
{
|
{
|
||||||
case SYS_exit:
|
|
||||||
case SYS_yield:
|
case SYS_yield:
|
||||||
case SYS_gettid:
|
case SYS_gettid:
|
||||||
case SYS_rand: result = __luna_syscall0(number); break;
|
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_sleep: result = __luna_syscall1(number, va_arg(ap, arg)); break;
|
||||||
case SYS_write:
|
case SYS_write:
|
||||||
case SYS_munmap:
|
case SYS_munmap:
|
||||||
|
Loading…
Reference in New Issue
Block a user