Kernel: Add a pstat() system call
Not part of C or POSIX, but since there is no procfs right now, I thought it would be nice to have an interface to query process information. It works like this: you pass the process ID and a pointer to a struct pstat (can be null). If the process ID is -1, the kernel picks the process with the highest PID. Then, if the pointer to a pstat struct is not null, the kernel fills it in with the process's information, and returns the process's PID.
This commit is contained in:
parent
31e0f0efed
commit
bcdcfc4b45
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user