diff --git a/ce/interp.c b/ce/interp.c index 096207d..df94b7a 100644 --- a/ce/interp.c +++ b/ce/interp.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -80,6 +81,22 @@ static void terminfo (struct context* context) { cprintf (context, "%zu x %zu\n", cols, rows); } +static void procinfo (struct context* context) { + struct proc_info* infos = malloc (sizeof (struct proc_info) * 1024); + memset (infos, 0, sizeof (struct proc_info) * 1024); + + int count = get_proc_info (infos, 1024); + + const char* proc_states[] = {"ready", "suspended", "partial"}; + + for (int i = 0; i < count; i++) { + struct proc_info* info = &infos[i]; + cprintf (context, "%-40s CPU=%-2d EXEC_PID=%-4d FLAGS=%08x PGID=%-4d PID=%-4d STATE=%-10s\n", + info->name, info->cpu, info->exec_pid, info->flags, info->pgid, info->pid, + proc_states[info->state]); + } +} + static void mkdir (struct context* context, char** dir_paths, size_t dirs_count) { char volume[VOLUME_MAX]; const char* path; @@ -311,6 +328,7 @@ static void help (struct context* context) { cprintf (context, "terminfo\n"); cprintf (context, "cls\n"); cprintf (context, "mkvol \n"); + cprintf (context, "procinfo\n"); cprintf (context, "quit\n"); } @@ -384,6 +402,8 @@ static void execute_cmd (struct ast_cmd* cmd, struct context* context) { mkvol (context, cmd->args[0], cmd->args[1], cmd->args[2]); else cprintf (context, "ERROR No volume key, filesystem type or device key provided\n"); + } else if (strcmp (cmd->name, "procinfo") == 0) { + procinfo (context); } else { char volume[VOLUME_MAX]; const char* path; diff --git a/include/proc_info.h b/include/proc_info.h new file mode 100644 index 0000000..a864e83 --- /dev/null +++ b/include/proc_info.h @@ -0,0 +1,18 @@ +#ifndef _PROC_INFO_H +#define _PROC_INFO_H + +#include +#include +#include + +struct proc_info { + int pid; + int exec_pid; + uint32_t flags; + int cpu; + int state; + int pgid; + char name[PATH_MAX + VOLUME_MAX]; +}; + +#endif // _PROC_INFO_H diff --git a/include/syscall_defs.h b/include/syscall_defs.h index 814b74a..c379c96 100644 --- a/include/syscall_defs.h +++ b/include/syscall_defs.h @@ -37,5 +37,6 @@ #define SYS_GET_SELF_PID 34 #define SYS_STREAM_WRITE 35 #define SYS_STREAM_READ 36 +#define SYS_GET_PROC_INFO 37 #endif // _M_SYSCALL_DEFS_H diff --git a/kernel/amd64/proc.c b/kernel/amd64/proc.c index b5d54fe..72d13d6 100644 --- a/kernel/amd64/proc.c +++ b/kernel/amd64/proc.c @@ -89,6 +89,8 @@ struct proc* proc_clone (struct proc* proto, uintptr_t vstack_top, uintptr_t ent spin_lock (&proto->lock, &fpt); + memcpy (proc->name, proto->name, sizeof (proto->name)); + proc->procgroup = proto->procgroup; procgroup_attach (proc->procgroup, proc); diff --git a/kernel/proc/proc.c b/kernel/proc/proc.c index 5581c12..fd26de7 100644 --- a/kernel/proc/proc.c +++ b/kernel/proc/proc.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -16,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -51,6 +53,7 @@ struct proc* kproc_create (void) { kproc->flags |= PROC_KPROC; kproc->state = PROC_READY; kproc->pid = proc_alloc_pid (); + snprintf (kproc->name, sizeof (kproc->name), "KPROC CPU %u", thiscpu->id); kproc->procgroup = procgroup_create (); procgroup_attach (kproc->procgroup, kproc); @@ -64,6 +67,56 @@ struct proc* kproc_create (void) { return kproc; } +size_t proc_populate_proc_infos (struct proc_info* proc_info, size_t count) { + uint64_t fpt, fp, fpg; + + if (count > PIDS_MAX) { + count = PIDS_MAX; + } + + spin_lock (&proc_tree_lock, &fpt); + + struct rb_node_link* node; + rbtree_first (&proc_tree, node); + + size_t i = 0; + + while (node != NULL && i < count) { + struct rb_node_link* next; + rbtree_next (node, next); + + struct proc* proc = rbtree_entry (node, struct proc, proc_tree_link); + + node = next; + + spin_lock (&proc->lock, &fp); + struct procgroup* procgroup = proc->procgroup; + spin_unlock (&proc->lock, fp); + + spin_lock (&procgroup->lock, &fpg); + spin_lock (&proc->lock, &fp); + + struct cpu* cpu = proc->cpu; + + proc_info[i].cpu = cpu->id; + proc_info[i].exec_pid = proc->exec_pid; + proc_info[i].flags = proc->flags; + proc_info[i].pid = proc->pid; + proc_info[i].state = proc->state; + proc_info[i].pgid = proc->procgroup->pgid; + memcpy (proc_info[i].name, proc->name, sizeof (proc->name)); + + spin_unlock (&proc->lock, fp); + spin_unlock (&procgroup->lock, fpg); + + i++; + } + + spin_unlock (&proc_tree_lock, fpt); + + return i; +} + static bool proc_check_elf (uint8_t* elf) { if (!((elf[0] == 0x7F) && (elf[1] == 'E') && (elf[2] == 'L') && (elf[3] == 'F'))) return false; @@ -173,6 +226,9 @@ struct proc* proc_from_file (struct proc* proc1, const char* volume, const char* struct proc* proc = proc_from_elf (temp_buffer); free (temp_buffer); + + snprintf (proc->name, sizeof (proc->name), "%s:%s", volume, path); + return proc; } diff --git a/kernel/proc/proc.h b/kernel/proc/proc.h index 8d016a7..bc7bf42 100644 --- a/kernel/proc/proc.h +++ b/kernel/proc/proc.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -48,6 +49,7 @@ struct proc { size_t mail_recv_size; char cwv[VOLUME_MAX]; struct proc_suspension_q done_sq; + char name[PATH_MAX + VOLUME_MAX]; }; void proc_sched (bool user); @@ -75,6 +77,8 @@ void proc_wait_for (struct proc* proc, struct reschedule_ctx* rctx, struct proc* void proc_irq_sched (void* arg, void* regs, bool user, struct reschedule_ctx* rctx); +size_t proc_populate_proc_infos (struct proc_info* proc_info, size_t count); + void proc_init (void); struct proc* kproc_create (void); diff --git a/kernel/syscall/syscall.c b/kernel/syscall/syscall.c index c5c0294..5352409 100644 --- a/kernel/syscall/syscall.c +++ b/kernel/syscall/syscall.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -1055,6 +1056,26 @@ DEFINE_SYSCALL (sys_stream_read) { return SYSRESULT (proc_stream_read (&stream_resource->u.stream, buffer, buffer_size)); } +/* int get_proc_int (struct proc_info* infos, size_t count) */ +DEFINE_SYSCALL (sys_get_proc_info) { + uint64_t fp; + + uintptr_t uvaddr_infos = a1; + size_t infos_count = (size_t)a2; + + spin_lock (&proc->lock, &fp); + struct procgroup* procgroup = proc->procgroup; + spin_unlock (&proc->lock, fp); + + struct proc_info* infos = + sys_get_user_buffer (procgroup, uvaddr_infos, infos_count * sizeof (struct proc_info)); + + if (infos == NULL) + return SYSRESULT (-ST_BAD_ADDRESS_SPACE); + + return SYSRESULT (proc_populate_proc_infos (infos, infos_count)); +} + static syscall_handler_func_t handler_table[] = { [SYS_QUIT] = &sys_quit, [SYS_TEST] = &sys_test, @@ -1092,6 +1113,7 @@ static syscall_handler_func_t handler_table[] = { [SYS_GET_SELF_PID] = &sys_get_self_pid, [SYS_STREAM_WRITE] = &sys_stream_write, [SYS_STREAM_READ] = &sys_stream_read, + [SYS_GET_PROC_INFO] = &sys_get_proc_info, }; syscall_handler_func_t syscall_find_handler (int syscall_num) { diff --git a/libsystem/system.c b/libsystem/system.c index c0d3ddf..b3557a0 100644 --- a/libsystem/system.c +++ b/libsystem/system.c @@ -110,3 +110,7 @@ int stream_write (int pgid, int rid, void* buffer, size_t size) { int stream_read (int pgid, int rid, void* buffer, size_t size) { return (int)do_syscall (SYS_STREAM_READ, pgid, rid, buffer, size); } + +int get_proc_info (struct proc_info* infos, size_t count) { + return (int)do_syscall (SYS_GET_PROC_INFO, infos, count); +} diff --git a/libsystem/system.h b/libsystem/system.h index 9763c81..3c79b1f 100644 --- a/libsystem/system.h +++ b/libsystem/system.h @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -114,4 +115,7 @@ int stream_write (int pgid, int rid, void* buffer, size_t size); /* Read from a stream */ int stream_read (int pgid, int rid, void* buffer, size_t size); +/* get process information */ +int get_proc_info (struct proc_info* infos, size_t count); + #endif // _LIBMSL_M_SYSTEM_H