[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [tyndur-devel] [PATCH] kernel2: Syscall SYSCALL_PM_ENUMERATE_TASKS



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: pgpbGqV3GWYCY.pgp
Description: PGP signature