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); |