Changeset 52755f1 in mainline


Ignore:
Timestamp:
2008-06-03T14:53:31Z (17 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
aa48a9d
Parents:
5b86d10
Message:

support for SYS_SPAWN syscall
proper printf formatting
change the way init tasks are created

Location:
kernel/generic/src/proc
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/proc/task.c

    r5b86d10 r52755f1  
    129129                       
    130130#ifdef CONFIG_DEBUG
    131                         printf("Killing task %llu\n", id);
     131                        printf("Killing task %" PRIu64 "\n", id);
    132132#endif                 
    133133                        task_kill(id);
     
    234234}
    235235
    236 /** Create new task with 1 thread and run it
    237  *
    238  * @param program_addr Address of program executable image.
    239  * @param name Program name.
    240  *
    241  * @return Task of the running program or NULL on error.
    242  */
    243 task_t *task_run_program(void *program_addr, char *name)
    244 {
    245         as_t *as;
    246         as_area_t *a;
    247         unsigned int rc;
    248         thread_t *t;
    249         task_t *task;
    250         uspace_arg_t *kernel_uarg;
    251 
    252         as = as_create(0);
    253         ASSERT(as);
    254 
    255         rc = elf_load((elf_header_t *) program_addr, as);
    256         if (rc != EE_OK) {
    257                 as_destroy(as);
    258                 return NULL;
    259         }
    260        
    261         kernel_uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t), 0);
     236/** Syscall for reading task ID from userspace.
     237 *
     238 * @param uspace_task_id Userspace address of 8-byte buffer where to store
     239 * current task ID.
     240 *
     241 * @return 0 on success or an error code from @ref errno.h.
     242 */
     243unative_t sys_task_get_id(task_id_t *uspace_task_id)
     244{
     245        /*
     246         * No need to acquire lock on TASK because taskid
     247         * remains constant for the lifespan of the task.
     248         */
     249        return (unative_t) copy_to_uspace(uspace_task_id, &TASK->taskid,
     250            sizeof(TASK->taskid));
     251}
     252
     253unative_t sys_task_spawn(void *image, size_t size)
     254{
     255        void *kimage = malloc(size, 0);
     256        if (kimage == NULL)
     257                return ENOMEM;
     258       
     259        int rc = copy_from_uspace(kimage, image, size);
     260        if (rc != EOK)
     261                return rc;
     262       
     263        uspace_arg_t *kernel_uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t), 0);
     264        if (kernel_uarg == NULL) {
     265                free(kimage);
     266                return ENOMEM;
     267        }
     268       
    262269        kernel_uarg->uspace_entry =
    263             (void *) ((elf_header_t *) program_addr)->e_entry;
     270            (void *) ((elf_header_t *) kimage)->e_entry;
    264271        kernel_uarg->uspace_stack = (void *) USTACK_ADDRESS;
    265272        kernel_uarg->uspace_thread_function = NULL;
     
    267274        kernel_uarg->uspace_uarg = NULL;
    268275       
    269         task = task_create(as, name);
    270         ASSERT(task);
    271 
    272         /*
    273          * Create the data as_area.
    274          */
    275         a = as_area_create(as, AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE,
    276             LOADED_PROG_STACK_PAGES_NO * PAGE_SIZE, USTACK_ADDRESS,
    277             AS_AREA_ATTR_NONE, &anon_backend, NULL);
    278 
    279         /*
    280          * Create the main thread.
    281          */
    282         t = thread_create(uinit, kernel_uarg, task, THREAD_FLAG_USPACE,
    283             "uinit", false);
    284         ASSERT(t);
    285        
    286         thread_ready(t);
    287 
    288         return task;
    289 }
    290 
    291 /** Syscall for reading task ID from userspace.
    292  *
    293  * @param uspace_task_id Userspace address of 8-byte buffer where to store
    294  * current task ID.
    295  *
    296  * @return 0 on success or an error code from @ref errno.h.
    297  */
    298 unative_t sys_task_get_id(task_id_t *uspace_task_id)
    299 {
    300         /*
    301          * No need to acquire lock on TASK because taskid
    302          * remains constant for the lifespan of the task.
    303          */
    304         return (unative_t) copy_to_uspace(uspace_task_id, &TASK->taskid,
    305             sizeof(TASK->taskid));
     276        as_t *as = as_create(0);
     277        if (as == NULL) {
     278                free(kernel_uarg);
     279                free(kimage);
     280                return ENOMEM;
     281        }
     282       
     283        unsigned int erc = elf_load((elf_header_t *) kimage, as);
     284        if (erc != EE_OK) {
     285                as_destroy(as);
     286                free(kernel_uarg);
     287                free(kimage);
     288                return ENOENT;
     289        }
     290       
     291        as_area_t *area = as_area_create(as,
     292                AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE,
     293                LOADED_PROG_STACK_PAGES_NO * PAGE_SIZE, USTACK_ADDRESS,
     294                AS_AREA_ATTR_NONE, &anon_backend, NULL);
     295        if (area == NULL) {
     296                as_destroy(as);
     297                free(kernel_uarg);
     298                free(kimage);
     299                return ENOMEM;
     300        }
     301       
     302        task_t *task = task_create(as, "app");
     303        if (task == NULL) {
     304                as_destroy(as);
     305                free(kernel_uarg);
     306                free(kimage);
     307                return ENOENT;
     308        }
     309       
     310        // FIXME: control the capabilities
     311        cap_set(task, cap_get(TASK));
     312       
     313        thread_t *thread = thread_create(uinit, kernel_uarg, task,
     314                THREAD_FLAG_USPACE, "user", false);
     315        if (thread == NULL) {
     316                task_destroy(task);
     317                as_destroy(as);
     318                free(kernel_uarg);
     319                free(kimage);
     320                return ENOENT;
     321        }
     322       
     323        thread_ready(thread);
     324       
     325        return EOK;
    306326}
    307327
     
    421441        char suffix;
    422442        order(task_get_accounting(t), &cycles, &suffix);
    423        
    424         if (sizeof(void *) == 4)
    425                 printf("%-6llu %-10s %-3ld %#10zx %#10zx %9llu%c %7zd %6zd",
    426                 t->taskid, t->name, t->context, t, t->as, cycles, suffix,
    427                     t->refcount, atomic_get(&t->active_calls));
    428         else
    429                 printf("%-6llu %-10s %-3ld %#18zx %#18zx %9llu%c %7zd %6zd",
    430                     t->taskid, t->name, t->context, t, t->as, cycles, suffix,
    431                 t->refcount, atomic_get(&t->active_calls));
     443
     444#ifdef __32_BITS__     
     445        printf("%-6" PRIu64 " %-10s %-3" PRIu32 " %10p %10p %9" PRIu64 "%c %7ld %6ld",
     446                t->taskid, t->name, t->context, t, t->as, cycles, suffix,
     447                atomic_get(&t->refcount), atomic_get(&t->active_calls));
     448#endif
     449
     450#ifdef __64_BITS__
     451        printf("%-6" PRIu64 " %-10s %-3" PRIu32 " %18p %18p %9" PRIu64 "%c %7ld %6ld",
     452                t->taskid, t->name, t->context, t, t->as, cycles, suffix,
     453                atomic_get(&t->refcount), atomic_get(&t->active_calls));
     454#endif
     455
    432456        for (j = 0; j < IPC_MAX_PHONES; j++) {
    433457                if (t->phones[j].callee)
    434                         printf(" %zd:%#zx", j, t->phones[j].callee);
     458                        printf(" %d:%p", j, t->phones[j].callee);
    435459        }
    436460        printf("\n");
     
    448472        ipl = interrupts_disable();
    449473        spinlock_lock(&tasks_lock);
    450        
    451         if (sizeof(void *) == 4) {
    452                 printf("taskid name       ctx address    as         "
    453                         "cycles     threads calls  callee\n");
    454                 printf("------ ---------- --- ---------- ---------- "
    455                         "---------- ------- ------ ------>\n");
    456         } else {
    457                 printf("taskid name       ctx address            as                 "
    458                         "cycles     threads calls  callee\n");
    459                 printf("------ ---------- --- ------------------ ------------------ "
    460                         "---------- ------- ------ ------>\n");
    461         }
     474
     475#ifdef __32_BITS__     
     476        printf("taskid name       ctx address    as         "
     477                "cycles     threads calls  callee\n");
     478        printf("------ ---------- --- ---------- ---------- "
     479                "---------- ------- ------ ------>\n");
     480#endif
     481
     482#ifdef __64_BITS__
     483        printf("taskid name       ctx address            as                 "
     484                "cycles     threads calls  callee\n");
     485        printf("------ ---------- --- ------------------ ------------------ "
     486                "---------- ------- ------ ------>\n");
     487#endif
    462488
    463489        avltree_walk(&tasks_tree, task_print_walker, NULL);
  • kernel/generic/src/proc/thread.c

    r5b86d10 r52755f1  
    6868#include <syscall/copy.h>
    6969#include <errno.h>
    70 #include <console/klog.h>
     70
     71
     72#ifndef LOADED_PROG_STACK_PAGES_NO
     73#define LOADED_PROG_STACK_PAGES_NO 1
     74#endif
    7175
    7276
     
    444448                if (THREAD->flags & THREAD_FLAG_USPACE) {
    445449                        ipc_cleanup();
    446                         futex_cleanup();
    447                         klog_printf("Cleanup of task %llu completed.",
    448                             TASK->taskid);
     450                        futex_cleanup();
     451                        LOG("Cleanup of task %" PRIu64" completed.", TASK->taskid);
    449452                }
    450453        }
     
    582585static bool thread_walker(avltree_node_t *node, void *arg)
    583586{
    584         thread_t *t;
    585                
    586         t = avltree_get_instance(node, thread_t, threads_tree_node);
    587 
     587        thread_t *t = avltree_get_instance(node, thread_t, threads_tree_node);
     588       
    588589        uint64_t cycles;
    589590        char suffix;
    590591        order(t->cycles, &cycles, &suffix);
    591        
    592         if (sizeof(void *) == 4)
    593                 printf("%-6llu %-10s %#10zx %-8s %#10zx %-3ld %#10zx %#10zx %9llu%c ",
    594                     t->tid, t->name, t, thread_states[t->state], t->task,
    595                 t->task->context, t->thread_code, t->kstack, cycles, suffix);
    596         else
    597                 printf("%-6llu %-10s %#18zx %-8s %#18zx %-3ld %#18zx %#18zx %9llu%c ",
    598                     t->tid, t->name, t, thread_states[t->state], t->task,
    599                 t->task->context, t->thread_code, t->kstack, cycles, suffix);
     592
     593#ifdef __32_BITS__
     594        printf("%-6" PRIu64" %-10s %10p %-8s %10p %-3" PRIu32 " %10p %10p %9" PRIu64 "%c ",
     595            t->tid, t->name, t, thread_states[t->state], t->task,
     596        t->task->context, t->thread_code, t->kstack, cycles, suffix);
     597#endif
     598
     599#ifdef __64_BITS__
     600        printf("%-6" PRIu64" %-10s %18p %-8s %18p %-3" PRIu32 " %18p %18p %9" PRIu64 "%c ",
     601            t->tid, t->name, t, thread_states[t->state], t->task,
     602        t->task->context, t->thread_code, t->kstack, cycles, suffix);
     603#endif
    600604                       
    601605        if (t->cpu)
    602                 printf("%-4zd", t->cpu->id);
     606                printf("%-4u", t->cpu->id);
    603607        else
    604608                printf("none");
    605609                       
    606610        if (t->state == Sleeping) {
    607                 if (sizeof(uintptr_t) == 4)
    608                         printf(" %#10zx", t->sleep_queue);
    609                 else
    610                         printf(" %#18zx", t->sleep_queue);
     611#ifdef __32_BITS__
     612                printf(" %10p", t->sleep_queue);
     613#endif
     614
     615#ifdef __64_BITS__
     616                printf(" %18p", t->sleep_queue);
     617#endif
    611618        }
    612619                       
     
    624631        ipl = interrupts_disable();
    625632        spinlock_lock(&threads_lock);
    626        
    627         if (sizeof(uintptr_t) == 4) {
    628                 printf("tid    name       address    state    task       "
    629                         "ctx code       stack      cycles     cpu  "
    630                         "waitqueue\n");
    631                 printf("------ ---------- ---------- -------- ---------- "
    632                         "--- ---------- ---------- ---------- ---- "
    633                         "----------\n");
    634         } else {
    635                 printf("tid    name       address            state    task               "
    636                         "ctx code               stack              cycles     cpu  "
    637                         "waitqueue\n");
    638                 printf("------ ---------- ------------------ -------- ------------------ "
    639                         "--- ------------------ ------------------ ---------- ---- "
    640                         "------------------\n");
    641         }
     633
     634#ifdef __32_BITS__     
     635        printf("tid    name       address    state    task       "
     636                "ctx code       stack      cycles     cpu  "
     637                "waitqueue\n");
     638        printf("------ ---------- ---------- -------- ---------- "
     639                "--- ---------- ---------- ---------- ---- "
     640                "----------\n");
     641#endif
     642
     643#ifdef __64_BITS__
     644        printf("tid    name       address            state    task               "
     645                "ctx code               stack              cycles     cpu  "
     646                "waitqueue\n");
     647        printf("------ ---------- ------------------ -------- ------------------ "
     648                "--- ------------------ ------------------ ---------- ---- "
     649                "------------------\n");
     650#endif
    642651
    643652        avltree_walk(&threads_tree, thread_walker, NULL);
     
    663672       
    664673        return node != NULL;
     674}
     675
     676
     677/** Create new user task with 1 thread from image
     678 *
     679 * @param program_addr Address of program executable image.
     680 * @param name Program name.
     681 *
     682 * @return Initialized main thread of the task or NULL on error.
     683 */
     684thread_t *thread_create_program(void *program_addr, char *name)
     685{
     686        as_t *as;
     687        as_area_t *area;
     688        unsigned int rc;
     689        task_t *task;
     690        uspace_arg_t *kernel_uarg;
     691       
     692        kernel_uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t), 0);
     693        if (kernel_uarg == NULL)
     694                return NULL;
     695       
     696        kernel_uarg->uspace_entry =
     697            (void *) ((elf_header_t *) program_addr)->e_entry;
     698        kernel_uarg->uspace_stack = (void *) USTACK_ADDRESS;
     699        kernel_uarg->uspace_thread_function = NULL;
     700        kernel_uarg->uspace_thread_arg = NULL;
     701        kernel_uarg->uspace_uarg = NULL;
     702
     703        as = as_create(0);
     704        if (as == NULL) {
     705                free(kernel_uarg);
     706                return NULL;
     707        }
     708
     709        rc = elf_load((elf_header_t *) program_addr, as);
     710        if (rc != EE_OK) {
     711                free(kernel_uarg);
     712                as_destroy(as);
     713                return NULL;
     714        }
     715       
     716        /*
     717         * Create the data as_area.
     718         */
     719        area = as_area_create(as,
     720                AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE,
     721                LOADED_PROG_STACK_PAGES_NO * PAGE_SIZE, USTACK_ADDRESS,
     722                AS_AREA_ATTR_NONE, &anon_backend, NULL);
     723        if (area == NULL) {
     724                free(kernel_uarg);
     725                as_destroy(as);
     726                return NULL;
     727        }
     728       
     729        task = task_create(as, name);
     730        if (task == NULL) {
     731                free(kernel_uarg);
     732                as_destroy(as);
     733                return NULL;
     734        }
     735       
     736        /*
     737         * Create the main thread.
     738         */
     739        return thread_create(uinit, kernel_uarg, task, THREAD_FLAG_USPACE,
     740            "uinit", false);
    665741}
    666742
Note: See TracChangeset for help on using the changeset viewer.