Subversion Repositories HelenOS

Rev

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

Rev 2927 Rev 3149
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
 *