Subversion Repositories HelenOS

Rev

Rev 3004 | Rev 3150 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3004 Rev 3149
Line 134... Line 134...
134
           
134
           
135
            spinlock_unlock(&tasks_lock);
135
            spinlock_unlock(&tasks_lock);
136
            interrupts_restore(ipl);
136
            interrupts_restore(ipl);
137
           
137
           
138
#ifdef CONFIG_DEBUG
138
#ifdef CONFIG_DEBUG
139
            printf("Killing task %llu\n", id);
139
            printf("Killing task %" PRIu64 "\n", id);
140
#endif          
140
#endif          
141
            task_kill(id);
141
            task_kill(id);
142
            thread_usleep(10000);
142
            thread_usleep(10000);
143
        } else {
143
        } else {
144
            spinlock_unlock(&tasks_lock);
144
            spinlock_unlock(&tasks_lock);
Line 247... Line 247...
247
 * @param entry_addr Program entry-point address in program address space.
247
 * @param entry_addr Program entry-point address in program address space.
248
 * @param name Program name.
248
 * @param name Program name.
249
 *
249
 *
250
 * @return Task of the running program or NULL on error.
250
 * @return Task of the running program or NULL on error.
251
 */
251
 */
252
task_t *task_create_from_as(as_t *as, uintptr_t entry_addr, char *name)
252
task_t *task_create_from_as(as_t *as, uintptr_t entry_addr, char *name
-
 
253
    thread_t **thr)
253
{
254
{
254
    as_area_t *a;
255
    as_area_t *a;
255
    thread_t *t;
256
    thread_t *t;
256
    task_t *task;
257
    task_t *task;
257
    uspace_arg_t *kernel_uarg;
258
    uspace_arg_t *kernel_uarg;
Line 277... Line 278...
277
     * Create the main thread.
278
     * Create the main thread.
278
     */
279
     */
279
    t = thread_create(uinit, kernel_uarg, task, THREAD_FLAG_USPACE,
280
    t = thread_create(uinit, kernel_uarg, task, THREAD_FLAG_USPACE,
280
        "uinit", false);
281
        "uinit", false);
281
    ASSERT(t);
282
    ASSERT(t);
-
 
283
 
-
 
284
    *thr = t;
282
   
285
   
283
    return task;
286
    return task;
284
}
287
}
285
 
288
 
286
/** Parse an executable image in the physical memory.
289
/** Parse an executable image in the physical memory.
Line 293... Line 296...
293
 * @param name Program name.
296
 * @param name Program name.
294
 * @param task Where to store the pointer to the newly created task.
297
 * @param task Where to store the pointer to the newly created task.
295
 *
298
 *
296
 * @return EOK on success or negative error code.
299
 * @return EOK on success or negative error code.
297
 */
300
 */
298
int task_parse_initial(void *program_addr, char *name, task_t **task)
301
int task_parse_initial(void *program_addr, char *name, thread_t **t)
299
{
302
{
300
    as_t *as;
303
    as_t *as;
301
    unsigned int rc;
304
    unsigned int rc;
-
 
305
    task_t *task;
302
 
306
 
303
    as = as_create(0);
307
    as = as_create(0);
304
    ASSERT(as);
308
    ASSERT(as);
305
 
309
 
306
    rc = elf_load((elf_header_t *) program_addr, as, 0);
310
    rc = elf_load((elf_header_t *) program_addr, as, 0);
Line 314... Line 318...
314
        ASSERT(program_loader == NULL);
318
        ASSERT(program_loader == NULL);
315
        program_loader = program_addr;
319
        program_loader = program_addr;
316
        return EOK;
320
        return EOK;
317
    }
321
    }
318
 
322
 
319
    *task = task_create_from_as(as, ((elf_header_t *) program_addr)->e_entry,
323
    task = task_create_from_as(as, ((elf_header_t *) program_addr)->e_entry,
320
        name);
324
        name, t);
321
 
325
 
322
    return EOK;
326
    return EOK;
323
}
327
}
324
 
328
 
325
/** Create a task from the program loader image.
329
/** Create a task from the program loader image.
Line 391... Line 395...
391
 *
395
 *
392
 * @param uspace_phone_id Userspace address where to store the phone id.
396
 * @param uspace_phone_id Userspace address where to store the phone id.
393
 *
397
 *
394
 * @return 0 on success or an error code from @ref errno.h.
398
 * @return 0 on success or an error code from @ref errno.h.
395
 */
399
 */
396
unative_t sys_task_spawn(int *uspace_phone_id)
400
unative_t sys_task_spawn_loader(int *uspace_phone_id)
397
{
401
{
398
    task_t *t;
402
    task_t *t;
399
    int fake_id;
403
    int fake_id;
400
    int rc;
404
    int rc;
401
    int phone_id;
405
    int phone_id;
Line 431... Line 435...
431
    task_ready(t);
435
    task_ready(t);
432
 
436
 
433
    return EOK;
437
    return EOK;
434
}
438
}
435
 
439
 
-
 
440
unative_t sys_task_spawn(void *image, size_t size)
-
 
441
{
-
 
442
    void *kimage = malloc(size, 0);
-
 
443
    if (kimage == NULL)
-
 
444
        return ENOMEM;
-
 
445
   
-
 
446
    int rc = copy_from_uspace(kimage, image, size);
-
 
447
    if (rc != EOK)
-
 
448
        return rc;
-
 
449
   
-
 
450
    uspace_arg_t *kernel_uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t), 0);
-
 
451
    if (kernel_uarg == NULL) {
-
 
452
        free(kimage);
-
 
453
        return ENOMEM;
-
 
454
    }
-
 
455
   
-
 
456
    kernel_uarg->uspace_entry =
-
 
457
        (void *) ((elf_header_t *) kimage)->e_entry;
-
 
458
    kernel_uarg->uspace_stack = (void *) USTACK_ADDRESS;
-
 
459
    kernel_uarg->uspace_thread_function = NULL;
-
 
460
    kernel_uarg->uspace_thread_arg = NULL;
-
 
461
    kernel_uarg->uspace_uarg = NULL;
-
 
462
   
-
 
463
    as_t *as = as_create(0);
-
 
464
    if (as == NULL) {
-
 
465
        free(kernel_uarg);
-
 
466
        free(kimage);
-
 
467
        return ENOMEM;
-
 
468
    }
-
 
469
   
-
 
470
    unsigned int erc = elf_load((elf_header_t *) kimage, as);
-
 
471
    if (erc != EE_OK) {
-
 
472
        as_destroy(as);
-
 
473
        free(kernel_uarg);
-
 
474
        free(kimage);
-
 
475
        return ENOENT;
-
 
476
    }
-
 
477
   
-
 
478
    as_area_t *area = as_area_create(as,
-
 
479
        AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE,
-
 
480
        LOADED_PROG_STACK_PAGES_NO * PAGE_SIZE, USTACK_ADDRESS,
-
 
481
        AS_AREA_ATTR_NONE, &anon_backend, NULL);
-
 
482
    if (area == NULL) {
-
 
483
        as_destroy(as);
-
 
484
        free(kernel_uarg);
-
 
485
        free(kimage);
-
 
486
        return ENOMEM;
-
 
487
    }
-
 
488
   
-
 
489
    task_t *task = task_create(as, "app");
-
 
490
    if (task == NULL) {
-
 
491
        as_destroy(as);
-
 
492
        free(kernel_uarg);
-
 
493
        free(kimage);
-
 
494
        return ENOENT;
-
 
495
    }
-
 
496
   
-
 
497
    // FIXME: control the capabilities
-
 
498
    cap_set(task, cap_get(TASK));
-
 
499
   
-
 
500
    thread_t *thread = thread_create(uinit, kernel_uarg, task,
-
 
501
        THREAD_FLAG_USPACE, "user", false);
-
 
502
    if (thread == NULL) {
-
 
503
        task_destroy(task);
-
 
504
        as_destroy(as);
-
 
505
        free(kernel_uarg);
-
 
506
        free(kimage);
-
 
507
        return ENOENT;
-
 
508
    }
-
 
509
   
-
 
510
    thread_ready(thread);
-
 
511
   
-
 
512
    return EOK;
-
 
513
}
-
 
514
 
436
/** Find task structure corresponding to task ID.
515
/** Find task structure corresponding to task ID.
437
 *
516
 *
438
 * The tasks_lock must be already held by the caller of this function
517
 * The tasks_lock must be already held by the caller of this function
439
 * and interrupts must be disabled.
518
 * and interrupts must be disabled.
440
 *
519
 *
Line 546... Line 625...
546
    spinlock_lock(&t->lock);
625
    spinlock_lock(&t->lock);
547
           
626
           
548
    uint64_t cycles;
627
    uint64_t cycles;
549
    char suffix;
628
    char suffix;
550
    order(task_get_accounting(t), &cycles, &suffix);
629
    order(task_get_accounting(t), &cycles, &suffix);
551
   
630
 
552
    if (sizeof(void *) == 4)
631
#ifdef __32_BITS__  
553
        printf("%-6llu %-10s %-3ld %#10zx %#10zx %9llu%c %7zd %6zd",
632
    printf("%-6" PRIu64 " %-10s %-3" PRIu32 " %10p %10p %9" PRIu64 "%c %7ld %6ld",
554
            t->taskid, t->name, t->context, t, t->as, cycles, suffix,
633
        t->taskid, t->name, t->context, t, t->as, cycles, suffix,
555
            t->refcount, atomic_get(&t->active_calls));
634
        atomic_get(&t->refcount), atomic_get(&t->active_calls));
556
    else
635
#endif
-
 
636
 
-
 
637
#ifdef __64_BITS__
557
        printf("%-6llu %-10s %-3ld %#18zx %#18zx %9llu%c %7zd %6zd",
638
    printf("%-6" PRIu64 " %-10s %-3" PRIu32 " %18p %18p %9" PRIu64 "%c %7ld %6ld",
558
            t->taskid, t->name, t->context, t, t->as, cycles, suffix,
639
        t->taskid, t->name, t->context, t, t->as, cycles, suffix,
559
            t->refcount, atomic_get(&t->active_calls));
640
        atomic_get(&t->refcount), atomic_get(&t->active_calls));
-
 
641
#endif
-
 
642
 
560
    for (j = 0; j < IPC_MAX_PHONES; j++) {
643
    for (j = 0; j < IPC_MAX_PHONES; j++) {
561
        if (t->phones[j].callee)
644
        if (t->phones[j].callee)
562
            printf(" %zd:%#zx", j, t->phones[j].callee);
645
            printf(" %d:%p", j, t->phones[j].callee);
563
    }
646
    }
564
    printf("\n");
647
    printf("\n");
565
           
648
           
566
    spinlock_unlock(&t->lock);
649
    spinlock_unlock(&t->lock);
567
    return true;
650
    return true;
Line 573... Line 656...
573
    ipl_t ipl;
656
    ipl_t ipl;
574
   
657
   
575
    /* Messing with task structures, avoid deadlock */
658
    /* Messing with task structures, avoid deadlock */
576
    ipl = interrupts_disable();
659
    ipl = interrupts_disable();
577
    spinlock_lock(&tasks_lock);
660
    spinlock_lock(&tasks_lock);
578
   
661
 
579
    if (sizeof(void *) == 4) {
662
#ifdef __32_BITS__  
580
        printf("taskid name       ctx address    as         "
663
    printf("taskid name       ctx address    as         "
581
            "cycles     threads calls  callee\n");
664
        "cycles     threads calls  callee\n");
582
        printf("------ ---------- --- ---------- ---------- "
665
    printf("------ ---------- --- ---------- ---------- "
583
            "---------- ------- ------ ------>\n");
666
        "---------- ------- ------ ------>\n");
584
    } else {
667
#endif
-
 
668
 
-
 
669
#ifdef __64_BITS__
585
        printf("taskid name       ctx address            as                 "
670
    printf("taskid name       ctx address            as                 "
586
            "cycles     threads calls  callee\n");
671
        "cycles     threads calls  callee\n");
587
        printf("------ ---------- --- ------------------ ------------------ "
672
    printf("------ ---------- --- ------------------ ------------------ "
588
            "---------- ------- ------ ------>\n");
673
        "---------- ------- ------ ------>\n");
589
    }
674
#endif
590
 
675
 
591
    avltree_walk(&tasks_tree, task_print_walker, NULL);
676
    avltree_walk(&tasks_tree, task_print_walker, NULL);
592
 
677
 
593
    spinlock_unlock(&tasks_lock);
678
    spinlock_unlock(&tasks_lock);
594
    interrupts_restore(ipl);
679
    interrupts_restore(ipl);