Rev 2907 | Rev 3104 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2907 | Rev 3063 | ||
---|---|---|---|
Line 65... | Line 65... | ||
65 | #include <mm/slab.h> |
65 | #include <mm/slab.h> |
66 | #include <debug.h> |
66 | #include <debug.h> |
67 | #include <main/uinit.h> |
67 | #include <main/uinit.h> |
68 | #include <syscall/copy.h> |
68 | #include <syscall/copy.h> |
69 | #include <errno.h> |
69 | #include <errno.h> |
- | 70 | ||
- | 71 | ||
70 | #include <console/klog.h> |
72 | #ifndef LOADED_PROG_STACK_PAGES_NO |
- | 73 | #define LOADED_PROG_STACK_PAGES_NO 1 |
|
- | 74 | #endif |
|
71 | 75 | ||
72 | 76 | ||
73 | /** Thread states */ |
77 | /** Thread states */ |
74 | char *thread_states[] = { |
78 | char *thread_states[] = { |
75 | "Invalid", |
79 | "Invalid", |
Line 441... | Line 445... | ||
441 | * threads can only be created by threads of the same task. |
445 | * threads can only be created by threads of the same task. |
442 | * We are safe to perform cleanup. |
446 | * We are safe to perform cleanup. |
443 | */ |
447 | */ |
444 | if (THREAD->flags & THREAD_FLAG_USPACE) { |
448 | if (THREAD->flags & THREAD_FLAG_USPACE) { |
445 | ipc_cleanup(); |
449 | ipc_cleanup(); |
446 | futex_cleanup(); |
450 | futex_cleanup(); |
447 | klog_printf("Cleanup of task %llu completed.", |
451 | LOG("Cleanup of task %" PRIu64" completed.", TASK->taskid); |
448 | TASK->taskid); |
- | |
449 | } |
452 | } |
450 | } |
453 | } |
451 | 454 | ||
452 | restart: |
455 | restart: |
453 | ipl = interrupts_disable(); |
456 | ipl = interrupts_disable(); |
Line 579... | Line 582... | ||
579 | interrupts_restore(ipl); |
582 | interrupts_restore(ipl); |
580 | } |
583 | } |
581 | 584 | ||
582 | static bool thread_walker(avltree_node_t *node, void *arg) |
585 | static bool thread_walker(avltree_node_t *node, void *arg) |
583 | { |
586 | { |
584 | thread_t *t; |
- | |
585 | - | ||
586 | t = avltree_get_instance(node, thread_t, threads_tree_node); |
587 | thread_t *t = avltree_get_instance(node, thread_t, threads_tree_node); |
587 | 588 | ||
588 | uint64_t cycles; |
589 | uint64_t cycles; |
589 | char suffix; |
590 | char suffix; |
590 | order(t->cycles, &cycles, &suffix); |
591 | order(t->cycles, &cycles, &suffix); |
591 | 592 | ||
592 | if (sizeof(void *) == 4) |
593 | #ifdef __32_BITS__ |
593 | printf("%-6llu %-10s %#10zx %-8s %#10zx %-3ld %#10zx %#10zx %9llu%c ", |
594 | printf("%-6" PRIu64" %-10s %10p %-8s %10p %-3" PRIu32 " %10p %10p %9" PRIu64 "%c ", |
594 | t->tid, t->name, t, thread_states[t->state], t->task, |
595 | t->tid, t->name, t, thread_states[t->state], t->task, |
595 | t->task->context, t->thread_code, t->kstack, cycles, suffix); |
596 | t->task->context, t->thread_code, t->kstack, cycles, suffix); |
596 | else |
597 | #endif |
- | 598 | ||
- | 599 | #ifdef __64_BITS__ |
|
597 | printf("%-6llu %-10s %#18zx %-8s %#18zx %-3ld %#18zx %#18zx %9llu%c ", |
600 | printf("%-6" PRIu64" %-10s %18p %-8s %18p %-3" PRIu32 " %18p %18p %9" PRIu64 "%c ", |
598 | t->tid, t->name, t, thread_states[t->state], t->task, |
601 | t->tid, t->name, t, thread_states[t->state], t->task, |
599 | t->task->context, t->thread_code, t->kstack, cycles, suffix); |
602 | t->task->context, t->thread_code, t->kstack, cycles, suffix); |
- | 603 | #endif |
|
600 | 604 | ||
601 | if (t->cpu) |
605 | if (t->cpu) |
602 | printf("%-4zd", t->cpu->id); |
606 | printf("%-4u", t->cpu->id); |
603 | else |
607 | else |
604 | printf("none"); |
608 | printf("none"); |
605 | 609 | ||
606 | if (t->state == Sleeping) { |
610 | if (t->state == Sleeping) { |
607 | if (sizeof(uintptr_t) == 4) |
611 | #ifdef __32_BITS__ |
608 | printf(" %#10zx", t->sleep_queue); |
612 | printf(" %10p", t->sleep_queue); |
609 | else |
613 | #endif |
- | 614 | ||
- | 615 | #ifdef __64_BITS__ |
|
610 | printf(" %#18zx", t->sleep_queue); |
616 | printf(" %18p", t->sleep_queue); |
- | 617 | #endif |
|
611 | } |
618 | } |
612 | 619 | ||
613 | printf("\n"); |
620 | printf("\n"); |
614 | 621 | ||
615 | return true; |
622 | return true; |
Line 621... | Line 628... | ||
621 | ipl_t ipl; |
628 | ipl_t ipl; |
622 | 629 | ||
623 | /* Messing with thread structures, avoid deadlock */ |
630 | /* Messing with thread structures, avoid deadlock */ |
624 | ipl = interrupts_disable(); |
631 | ipl = interrupts_disable(); |
625 | spinlock_lock(&threads_lock); |
632 | spinlock_lock(&threads_lock); |
626 | 633 | ||
627 | if (sizeof(uintptr_t) == 4) { |
634 | #ifdef __32_BITS__ |
628 | printf("tid name address state task " |
635 | printf("tid name address state task " |
629 | "ctx code stack cycles cpu " |
636 | "ctx code stack cycles cpu " |
630 | "waitqueue\n"); |
637 | "waitqueue\n"); |
631 | printf("------ ---------- ---------- -------- ---------- " |
638 | printf("------ ---------- ---------- -------- ---------- " |
632 | "--- ---------- ---------- ---------- ---- " |
639 | "--- ---------- ---------- ---------- ---- " |
633 | "----------\n"); |
640 | "----------\n"); |
634 | } else { |
641 | #endif |
- | 642 | ||
- | 643 | #ifdef __64_BITS__ |
|
635 | printf("tid name address state task " |
644 | printf("tid name address state task " |
636 | "ctx code stack cycles cpu " |
645 | "ctx code stack cycles cpu " |
637 | "waitqueue\n"); |
646 | "waitqueue\n"); |
638 | printf("------ ---------- ------------------ -------- ------------------ " |
647 | printf("------ ---------- ------------------ -------- ------------------ " |
639 | "--- ------------------ ------------------ ---------- ---- " |
648 | "--- ------------------ ------------------ ---------- ---- " |
640 | "------------------\n"); |
649 | "------------------\n"); |
641 | } |
650 | #endif |
642 | 651 | ||
643 | avltree_walk(&threads_tree, thread_walker, NULL); |
652 | avltree_walk(&threads_tree, thread_walker, NULL); |
644 | 653 | ||
645 | spinlock_unlock(&threads_lock); |
654 | spinlock_unlock(&threads_lock); |
646 | interrupts_restore(ipl); |
655 | interrupts_restore(ipl); |
Line 663... | Line 672... | ||
663 | 672 | ||
664 | return node != NULL; |
673 | return node != NULL; |
665 | } |
674 | } |
666 | 675 | ||
667 | 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 | */ |
|
- | 684 | thread_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); |
|
- | 741 | } |
|
- | 742 | ||
- | 743 | ||
668 | /** Update accounting of current thread. |
744 | /** Update accounting of current thread. |
669 | * |
745 | * |
670 | * Note that thread_lock on THREAD must be already held and |
746 | * Note that thread_lock on THREAD must be already held and |
671 | * interrupts must be already disabled. |
747 | * interrupts must be already disabled. |
672 | * |
748 | * |