Subversion Repositories HelenOS

Rev

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

Rev 2802 Rev 3063
Line 126... Line 126...
126
           
126
           
127
            spinlock_unlock(&tasks_lock);
127
            spinlock_unlock(&tasks_lock);
128
            interrupts_restore(ipl);
128
            interrupts_restore(ipl);
129
           
129
           
130
#ifdef CONFIG_DEBUG
130
#ifdef CONFIG_DEBUG
131
            printf("Killing task %llu\n", id);
131
            printf("Killing task %" PRIu64 "\n", id);
132
#endif          
132
#endif          
133
            task_kill(id);
133
            task_kill(id);
134
            thread_usleep(10000);
134
            thread_usleep(10000);
135
        } else {
135
        } else {
136
            spinlock_unlock(&tasks_lock);
136
            spinlock_unlock(&tasks_lock);
Line 231... Line 231...
231
   
231
   
232
    free(t);
232
    free(t);
233
    TASK = NULL;
233
    TASK = NULL;
234
}
234
}
235
 
235
 
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);
-
 
262
    kernel_uarg->uspace_entry =
-
 
263
        (void *) ((elf_header_t *) program_addr)->e_entry;
-
 
264
    kernel_uarg->uspace_stack = (void *) USTACK_ADDRESS;
-
 
265
    kernel_uarg->uspace_thread_function = NULL;
-
 
266
    kernel_uarg->uspace_thread_arg = NULL;
-
 
267
    kernel_uarg->uspace_uarg = NULL;
-
 
268
   
-
 
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.
236
/** Syscall for reading task ID from userspace.
292
 *
237
 *
293
 * @param uspace_task_id Userspace address of 8-byte buffer where to store
238
 * @param uspace_task_id Userspace address of 8-byte buffer where to store
294
 * current task ID.
239
 * current task ID.
295
 *
240
 *
Line 303... Line 248...
303
     */
248
     */
304
    return (unative_t) copy_to_uspace(uspace_task_id, &TASK->taskid,
249
    return (unative_t) copy_to_uspace(uspace_task_id, &TASK->taskid,
305
        sizeof(TASK->taskid));
250
        sizeof(TASK->taskid));
306
}
251
}
307
 
252
 
-
 
253
unative_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
   
-
 
269
    kernel_uarg->uspace_entry =
-
 
270
        (void *) ((elf_header_t *) kimage)->e_entry;
-
 
271
    kernel_uarg->uspace_stack = (void *) USTACK_ADDRESS;
-
 
272
    kernel_uarg->uspace_thread_function = NULL;
-
 
273
    kernel_uarg->uspace_thread_arg = NULL;
-
 
274
    kernel_uarg->uspace_uarg = NULL;
-
 
275
   
-
 
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;
-
 
326
}
-
 
327
 
308
/** Find task structure corresponding to task ID.
328
/** Find task structure corresponding to task ID.
309
 *
329
 *
310
 * The tasks_lock must be already held by the caller of this function
330
 * The tasks_lock must be already held by the caller of this function
311
 * and interrupts must be disabled.
331
 * and interrupts must be disabled.
312
 *
332
 *
Line 418... Line 438...
418
    spinlock_lock(&t->lock);
438
    spinlock_lock(&t->lock);
419
           
439
           
420
    uint64_t cycles;
440
    uint64_t cycles;
421
    char suffix;
441
    char suffix;
422
    order(task_get_accounting(t), &cycles, &suffix);
442
    order(task_get_accounting(t), &cycles, &suffix);
423
   
443
 
424
    if (sizeof(void *) == 4)
444
#ifdef __32_BITS__  
425
        printf("%-6llu %-10s %-3ld %#10zx %#10zx %9llu%c %7zd %6zd",
445
    printf("%-6" PRIu64 " %-10s %-3" PRIu32 " %10p %10p %9" PRIu64 "%c %7ld %6ld",
426
            t->taskid, t->name, t->context, t, t->as, cycles, suffix,
446
        t->taskid, t->name, t->context, t, t->as, cycles, suffix,
427
            t->refcount, atomic_get(&t->active_calls));
447
        atomic_get(&t->refcount), atomic_get(&t->active_calls));
428
    else
448
#endif
-
 
449
 
-
 
450
#ifdef __64_BITS__
429
        printf("%-6llu %-10s %-3ld %#18zx %#18zx %9llu%c %7zd %6zd",
451
    printf("%-6" PRIu64 " %-10s %-3" PRIu32 " %18p %18p %9" PRIu64 "%c %7ld %6ld",
430
            t->taskid, t->name, t->context, t, t->as, cycles, suffix,
452
        t->taskid, t->name, t->context, t, t->as, cycles, suffix,
431
            t->refcount, atomic_get(&t->active_calls));
453
        atomic_get(&t->refcount), atomic_get(&t->active_calls));
-
 
454
#endif
-
 
455
 
432
    for (j = 0; j < IPC_MAX_PHONES; j++) {
456
    for (j = 0; j < IPC_MAX_PHONES; j++) {
433
        if (t->phones[j].callee)
457
        if (t->phones[j].callee)
434
            printf(" %zd:%#zx", j, t->phones[j].callee);
458
            printf(" %d:%p", j, t->phones[j].callee);
435
    }
459
    }
436
    printf("\n");
460
    printf("\n");
437
           
461
           
438
    spinlock_unlock(&t->lock);
462
    spinlock_unlock(&t->lock);
439
    return true;
463
    return true;
Line 445... Line 469...
445
    ipl_t ipl;
469
    ipl_t ipl;
446
   
470
   
447
    /* Messing with task structures, avoid deadlock */
471
    /* Messing with task structures, avoid deadlock */
448
    ipl = interrupts_disable();
472
    ipl = interrupts_disable();
449
    spinlock_lock(&tasks_lock);
473
    spinlock_lock(&tasks_lock);
450
   
474
 
451
    if (sizeof(void *) == 4) {
475
#ifdef __32_BITS__  
452
        printf("taskid name       ctx address    as         "
476
    printf("taskid name       ctx address    as         "
453
            "cycles     threads calls  callee\n");
477
        "cycles     threads calls  callee\n");
454
        printf("------ ---------- --- ---------- ---------- "
478
    printf("------ ---------- --- ---------- ---------- "
455
            "---------- ------- ------ ------>\n");
479
        "---------- ------- ------ ------>\n");
456
    } else {
480
#endif
-
 
481
 
-
 
482
#ifdef __64_BITS__
457
        printf("taskid name       ctx address            as                 "
483
    printf("taskid name       ctx address            as                 "
458
            "cycles     threads calls  callee\n");
484
        "cycles     threads calls  callee\n");
459
        printf("------ ---------- --- ------------------ ------------------ "
485
    printf("------ ---------- --- ------------------ ------------------ "
460
            "---------- ------- ------ ------>\n");
486
        "---------- ------- ------ ------>\n");
461
    }
487
#endif
462
 
488
 
463
    avltree_walk(&tasks_tree, task_print_walker, NULL);
489
    avltree_walk(&tasks_tree, task_print_walker, NULL);
464
 
490
 
465
    spinlock_unlock(&tasks_lock);
491
    spinlock_unlock(&tasks_lock);
466
    interrupts_restore(ipl);
492
    interrupts_restore(ipl);