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