On Wed, Aug 05 00:20, Kevin Wolf wrote: > + kernel2: Syscall SYSCALL_PM_ENUMERATE_TASKS (Speicherbedarf und > aktuelles eip bleiben momentan leer) > > Signed-off-by: Kevin Wolf <kevin@xxxxxxxxxx> > --- > src/kernel2/include/syscall.h | 4 ++ > src/kernel2/src/syscall.c | 3 ++ > src/kernel2/src/syscalls/pm.c | 77 +++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 84 insertions(+), 0 deletions(-) > > diff --git a/src/kernel2/include/syscall.h b/src/kernel2/include/syscall.h > index 6637ffd..b7ebfc9 100644 > --- a/src/kernel2/include/syscall.h > +++ b/src/kernel2/include/syscall.h > @@ -116,6 +116,10 @@ pid_t syscall_pm_create_process(vaddr_t start, uid_t uid, > /// Aktuellen Prozess beenden > void syscall_pm_exit_process(void); > > +/// Alle Prozesse auflisten > +void* syscall_pm_enumerate_tasks(void); > + > + > /// Speicher an einen anderen Prozess uebergeben > void syscall_init_child_page(pid_t pid, vaddr_t src, vaddr_t dest, > size_t size); > diff --git a/src/kernel2/src/syscall.c b/src/kernel2/src/syscall.c > index 58c82de..fcb9f66 100644 > --- a/src/kernel2/src/syscall.c > +++ b/src/kernel2/src/syscall.c > @@ -71,6 +71,9 @@ void syscall_init() > syscall_register(SYSCALL_PM_INIT_PAGE, &syscall_init_child_page, 4); > syscall_register(SYSCALL_PM_EXIT_PROCESS, &syscall_pm_exit_process, 0); > > + syscall_register(SYSCALL_PM_ENUMERATE_TASKS, > + &syscall_pm_enumerate_tasks, 0); > + > syscall_register(SYSCALL_SET_RPC_HANDLER, &syscall_set_rpc_handler, 1); > #if CONFIG_ARCH == ARCH_I386 > syscall_register(SYSCALL_FASTRPC, &syscall_fastrpc, 5); > diff --git a/src/kernel2/src/syscalls/pm.c b/src/kernel2/src/syscalls/pm.c > index b4f5cf7..750d3dc 100644 > --- a/src/kernel2/src/syscalls/pm.c > +++ b/src/kernel2/src/syscalls/pm.c > @@ -38,6 +38,7 @@ > #include <string.h> > > #include "syscall.h" > +#include "syscall_structs.h" > #include "tasks.h" > #include "cpu.h" > > @@ -234,3 +235,79 @@ void syscall_pm_wait_for_rpc(void) > syscall_pm_sleep(); > thread->status = PM_STATUS_WAIT_FOR_RPC; > } > + > +/** > + * Alle Prozesse auflisten > + * > + * @return Gibt einen Pointer auf neu allozierte Seiten zurueck, die > + * Informationen ueber alle laufenden Tasks enthalten. Der Pointer zeigt dabei > + * auf Daten vom Typ task_info_t. > + */ > +void* syscall_pm_enumerate_tasks(void) > +{ > + // Erst werden die Tasks gezaehlt, und die Groesse der > + // Informationen mit den Kommandozeilen wird errechnet. > + size_t task_count = 0; > + size_t result_size = sizeof(task_info_t); > + pm_process_t* task; > + unsigned int i; > + > + for (i = 0; (task = list_get_element_at(process_list, i)); i++) { > + task_count++; > + result_size += sizeof(task_info_task_t) + strlen(task->cmdline) + 1; > + } > + > + // Anzahl der Seiten berechnen, die die Informationen benoetigen. > + size_t result_page_count = PAGE_ALIGN_ROUND_UP(result_size) / PAGE_SIZE; > + > + // Jetzt wird eine freie Stelle im Adressraum des Prozesses > + // gesucht, wo die Task-Infos hingemappt werden koennen > + // FIXME Die Seiten muessen nicht physisch zusammenhaengend sein > + task_info_t* task_info = mmc_automap(&mmc_current_context(), > + pmm_alloc(result_page_count), result_page_count, MM_USER_START, > + MM_USER_END, PTE_P | PTE_W | PTE_U); > + > + // Der Groessen-Eintrag ist nur da, damit der Task die Pages > + // freigeben koennte. > + task_info->info_size = result_size; > + task_info->task_count = task_count; > + > + // Dieser Pointer zeigt direkt hinter das Array mit den > + // Task-Informationen. Dort werden die Kommandozeilen > + // hintereinander gespeichert, und aus den Task-Strukturen wird auf > + // sie verwiesen. > + char* cmdlines = (char*) task_info->tasks; > + cmdlines += task_count * sizeof(task_info_task_t); > + > + // Jetzt werden die Infos eingefuellt. > + for (i = 0; (task = list_get_element_at(process_list, i)); i++) { > + task_info->tasks[i].pid = task->pid; > + task_info->tasks[i].status = task->status; > + > + // TODO Ergibt strenggenommen keinen Sinn, evtl. ersten Thread? > + task_info->tasks[i].eip = 0; > + > + // Wenn der Task keinen Eltern-Task hat muessen wir aufpassen, > + // damit wir keinen Pagefault produzieren. > + if (task->parent == NULL) { > + task_info->tasks[i].parent_pid = 0; > + } else { > + task_info->tasks[i].parent_pid = task->parent->pid; > + } > + > + // Die Kommandozeile inklusive Nullbyte kopieren > + size_t cmdline_size = strlen(task->cmdline) + 1; > + memcpy(cmdlines, task->cmdline, cmdline_size); So ein strcpy ist schon was feines... ;-) > + > + // Den Pointer fuer die Kommandozeile setzen > + task_info->tasks[i].cmdline = cmdlines; > + > + // Den Zielpointer fuer die naechste Kommandozeile direkt > + // hinter die aktuelle setzen. > + cmdlines += cmdline_size; > + > + task_info->tasks[i].memory_used = 0; // TODO > + } > + > + return task_info; > +} Aber jo, sonst sieht das gut aus. Also wenn du das noch änderst: Acked-by: Antoine Kaufmann <toni@xxxxxxxxxx> -- Antoine Kaufmann <toni@xxxxxxxxxxxxxxxx>
Attachment:
pgpy7LsYAfInG.pgp
Description: PGP signature