diff --git a/kernel/include/sys/Syscall.h b/kernel/include/sys/Syscall.h index c1a71a52..6cbdce6e 100644 --- a/kernel/include/sys/Syscall.h +++ b/kernel/include/sys/Syscall.h @@ -23,8 +23,10 @@ #define SYS_waitpid 18 #define SYS_access 19 #define SYS_fstat 20 +#define SYS_pstat 21 struct stat; +struct pstat; namespace Syscall { @@ -52,3 +54,4 @@ void sys_fork(Context* context); void sys_waitpid(Context* context, long pid, int* wstatus, int options); void sys_access(Context* context, const char* path, int amode); void sys_fstat(Context* context, int fd, struct stat* buf); +void sys_pstat(Context* context, long pid, struct pstat* buf); diff --git a/kernel/src/sys/Syscall.cpp b/kernel/src/sys/Syscall.cpp index 3c44c500..01d3df12 100644 --- a/kernel/src/sys/Syscall.cpp +++ b/kernel/src/sys/Syscall.cpp @@ -32,6 +32,7 @@ void Syscall::entry(Context* context) case SYS_waitpid: sys_waitpid(context, (long)context->rdi, (int*)context->rsi, (int)context->rdx); break; case SYS_access: sys_access(context, (const char*)context->rdi, (int)context->rsi); break; case SYS_fstat: sys_fstat(context, (int)context->rdi, (struct stat*)context->rsi); break; + case SYS_pstat: sys_pstat(context, (long)context->rdi, (struct pstat*)context->rsi); break; default: context->rax = -ENOSYS; break; } VMM::exit_syscall_context(); diff --git a/kernel/src/thread/Scheduler.cpp b/kernel/src/thread/Scheduler.cpp index f41333a4..5526ba4d 100644 --- a/kernel/src/thread/Scheduler.cpp +++ b/kernel/src/thread/Scheduler.cpp @@ -374,10 +374,10 @@ void Scheduler::task_tick(Context* context) ASSERT(Interrupts::is_in_handler()); Interrupts::disable(); sched_decrement_sleep_times(); - if (sched_current_task->id == 0) return task_yield(context); sched_current_task->task_time -= frequency; sched_current_task->cpu_time += frequency; - if (sched_current_task->task_time < 0) + if (sched_current_task->id == 0) return task_yield(context); + if (sched_current_task->task_time <= 0) { sched_current_task->task_time = 0; task_yield(context); @@ -513,4 +513,50 @@ void sys_waitpid(Context* context, long pid, int* wstatus, } child->state = child->Exited; context->rax = (long)child->id; +} + +struct pstat +{ + long pt_pid; + long pt_ppid; + char pt_name[128]; + int pt_state; + long pt_time; +}; + +void sys_pstat(Context* context, long pid, struct pstat* buf) +{ + Task* task; + if (pid == -1) task = Scheduler::find_by_pid(free_tid - 1); + else if (pid == 0) + task = &idle_task; + else + task = Scheduler::find_by_pid(pid); + if (!task) + { + context->rax = -ESRCH; + return; + } + if (task->state == task->Exited) // we're just waiting for the reaper to reap it + { + context->rax = -ESRCH; + return; + } + if (buf) + { + struct pstat* kpstat = obtain_user_ref(buf); + if (!kpstat) + { + context->rax = -EFAULT; + return; + } + kpstat->pt_pid = task->id; + kpstat->pt_ppid = task->ppid; + kpstat->pt_state = (int)task->state; + kpstat->pt_time = (long)task->cpu_time; + strlcpy(kpstat->pt_name, task->name, sizeof(kpstat->pt_name)); + release_user_ref(kpstat); + } + context->rax = task->id; + return; } \ No newline at end of file