Subversion Repositories HelenOS

Rev

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

Rev 3034 Rev 3424
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 289... Line 293...
289
    t = (thread_t *) slab_alloc(thread_slab, 0);
293
    t = (thread_t *) slab_alloc(thread_slab, 0);
290
    if (!t)
294
    if (!t)
291
        return NULL;
295
        return NULL;
292
   
296
   
293
    /* Not needed, but good for debugging */
297
    /* Not needed, but good for debugging */
294
    memsetb((uintptr_t) t->kstack, THREAD_STACK_SIZE * 1 << STACK_FRAMES,
298
    memsetb(t->kstack, THREAD_STACK_SIZE * 1 << STACK_FRAMES, 0);
295
        0);
-
 
296
   
299
   
297
    ipl = interrupts_disable();
300
    ipl = interrupts_disable();
298
    spinlock_lock(&tidlock);
301
    spinlock_lock(&tidlock);
299
    t->tid = ++last_tid;
302
    t->tid = ++last_tid;
300
    spinlock_unlock(&tidlock);
303
    spinlock_unlock(&tidlock);
Line 452... Line 455...
452
             * moment the task was created, new userspace threads
455
             * moment the task was created, new userspace threads
453
             * can only be created by threads of the same task.
456
             * can only be created by threads of the same task.
454
             * We are safe to perform cleanup.
457
             * We are safe to perform cleanup.
455
             */
458
             */
456
            ipc_cleanup();
459
            ipc_cleanup();
457
                futex_cleanup();
460
            futex_cleanup();
458
            klog_printf("Cleanup of task %llu completed.",
461
            LOG("Cleanup of task %" PRIu64" completed.", TASK->taskid);
459
                TASK->taskid);
-
 
460
        }
462
        }
461
    }
463
    }
462
 
464
 
463
restart:
465
restart:
464
    ipl = interrupts_disable();
466
    ipl = interrupts_disable();
Line 590... Line 592...
590
    interrupts_restore(ipl);
592
    interrupts_restore(ipl);
591
}
593
}
592
 
594
 
593
static bool thread_walker(avltree_node_t *node, void *arg)
595
static bool thread_walker(avltree_node_t *node, void *arg)
594
{
596
{
595
    thread_t *t;
-
 
596
       
-
 
597
    t = avltree_get_instance(node, thread_t, threads_tree_node);
597
    thread_t *t = avltree_get_instance(node, thread_t, threads_tree_node);
598
 
598
   
599
    uint64_t cycles;
599
    uint64_t cycles;
600
    char suffix;
600
    char suffix;
601
    order(t->cycles, &cycles, &suffix);
601
    order(t->cycles, &cycles, &suffix);
602
   
602
 
603
    if (sizeof(void *) == 4)
603
#ifdef __32_BITS__
604
        printf("%-6llu %-10s %#10zx %-8s %#10zx %-3ld %#10zx %#10zx %9llu%c ",
604
    printf("%-6" PRIu64" %-10s %10p %-8s %10p %-3" PRIu32 " %10p %10p %9" PRIu64 "%c ",
605
            t->tid, t->name, t, thread_states[t->state], t->task,
605
        t->tid, t->name, t, thread_states[t->state], t->task,
606
            t->task->context, t->thread_code, t->kstack, cycles, suffix);
606
        t->task->context, t->thread_code, t->kstack, cycles, suffix);
607
    else
607
#endif
-
 
608
 
-
 
609
#ifdef __64_BITS__
608
        printf("%-6llu %-10s %#18zx %-8s %#18zx %-3ld %#18zx %#18zx %9llu%c ",
610
    printf("%-6" PRIu64" %-10s %18p %-8s %18p %-3" PRIu32 " %18p %18p %9" PRIu64 "%c ",
609
            t->tid, t->name, t, thread_states[t->state], t->task,
611
        t->tid, t->name, t, thread_states[t->state], t->task,
610
            t->task->context, t->thread_code, t->kstack, cycles, suffix);
612
        t->task->context, t->thread_code, t->kstack, cycles, suffix);
-
 
613
#endif
611
           
614
           
612
    if (t->cpu)
615
    if (t->cpu)
613
        printf("%-4zd", t->cpu->id);
616
        printf("%-4u", t->cpu->id);
614
    else
617
    else
615
        printf("none");
618
        printf("none");
616
           
619
           
617
    if (t->state == Sleeping) {
620
    if (t->state == Sleeping) {
618
        if (sizeof(uintptr_t) == 4)
621
#ifdef __32_BITS__
619
            printf(" %#10zx", t->sleep_queue);
622
        printf(" %10p", t->sleep_queue);
620
        else
623
#endif
-
 
624
 
-
 
625
#ifdef __64_BITS__
621
            printf(" %#18zx", t->sleep_queue);
626
        printf(" %18p", t->sleep_queue);
-
 
627
#endif
622
    }
628
    }
623
           
629
           
624
    printf("\n");
630
    printf("\n");
625
 
631
 
626
    return true;
632
    return true;
Line 632... Line 638...
632
    ipl_t ipl;
638
    ipl_t ipl;
633
   
639
   
634
    /* Messing with thread structures, avoid deadlock */
640
    /* Messing with thread structures, avoid deadlock */
635
    ipl = interrupts_disable();
641
    ipl = interrupts_disable();
636
    spinlock_lock(&threads_lock);
642
    spinlock_lock(&threads_lock);
637
   
643
 
638
    if (sizeof(uintptr_t) == 4) {
644
#ifdef __32_BITS__  
639
        printf("tid    name       address    state    task       "
645
    printf("tid    name       address    state    task       "
640
            "ctx code       stack      cycles     cpu  "
646
        "ctx code       stack      cycles     cpu  "
641
            "waitqueue\n");
647
        "waitqueue\n");
642
        printf("------ ---------- ---------- -------- ---------- "
648
    printf("------ ---------- ---------- -------- ---------- "
643
            "--- ---------- ---------- ---------- ---- "
649
        "--- ---------- ---------- ---------- ---- "
644
            "----------\n");
650
        "----------\n");
645
    } else {
651
#endif
-
 
652
 
-
 
653
#ifdef __64_BITS__
646
        printf("tid    name       address            state    task               "
654
    printf("tid    name       address            state    task               "
647
            "ctx code               stack              cycles     cpu  "
655
        "ctx code               stack              cycles     cpu  "
648
            "waitqueue\n");
656
        "waitqueue\n");
649
        printf("------ ---------- ------------------ -------- ------------------ "
657
    printf("------ ---------- ------------------ -------- ------------------ "
650
            "--- ------------------ ------------------ ---------- ---- "
658
        "--- ------------------ ------------------ ---------- ---- "
651
            "------------------\n");
659
        "------------------\n");
652
    }
660
#endif
653
 
661
 
654
    avltree_walk(&threads_tree, thread_walker, NULL);
662
    avltree_walk(&threads_tree, thread_walker, NULL);
655
 
663
 
656
    spinlock_unlock(&threads_lock);
664
    spinlock_unlock(&threads_lock);
657
    interrupts_restore(ipl);
665
    interrupts_restore(ipl);
Line 674... Line 682...
674
   
682
   
675
    return node != NULL;
683
    return node != NULL;
676
}
684
}
677
 
685
 
678
 
686
 
-
 
687
/** Create new user task with 1 thread from image
-
 
688
 *
-
 
689
 * @param program_addr Address of program executable image.
-
 
690
 * @param name Program name.
-
 
691
 *
-
 
692
 * @return Initialized main thread of the task or NULL on error.
-
 
693
 */
-
 
694
thread_t *thread_create_program(void *program_addr, char *name)
-
 
695
{
-
 
696
    as_t *as;
-
 
697
    as_area_t *area;
-
 
698
    unsigned int rc;
-
 
699
    task_t *task;
-
 
700
    uspace_arg_t *kernel_uarg;
-
 
701
   
-
 
702
    kernel_uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t), 0);
-
 
703
    if (kernel_uarg == NULL)
-
 
704
        return NULL;
-
 
705
   
-
 
706
    kernel_uarg->uspace_entry =
-
 
707
        (void *) ((elf_header_t *) program_addr)->e_entry;
-
 
708
    kernel_uarg->uspace_stack = (void *) USTACK_ADDRESS;
-
 
709
    kernel_uarg->uspace_thread_function = NULL;
-
 
710
    kernel_uarg->uspace_thread_arg = NULL;
-
 
711
    kernel_uarg->uspace_uarg = NULL;
-
 
712
 
-
 
713
    as = as_create(0);
-
 
714
    if (as == NULL) {
-
 
715
        free(kernel_uarg);
-
 
716
        return NULL;
-
 
717
    }
-
 
718
 
-
 
719
    rc = elf_load((elf_header_t *) program_addr, as);
-
 
720
    if (rc != EE_OK) {
-
 
721
        free(kernel_uarg);
-
 
722
        as_destroy(as);
-
 
723
        return NULL;
-
 
724
    }
-
 
725
   
-
 
726
    /*
-
 
727
     * Create the data as_area.
-
 
728
     */
-
 
729
    area = as_area_create(as,
-
 
730
        AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE,
-
 
731
        LOADED_PROG_STACK_PAGES_NO * PAGE_SIZE, USTACK_ADDRESS,
-
 
732
        AS_AREA_ATTR_NONE, &anon_backend, NULL);
-
 
733
    if (area == NULL) {
-
 
734
        free(kernel_uarg);
-
 
735
        as_destroy(as);
-
 
736
        return NULL;
-
 
737
    }
-
 
738
   
-
 
739
    task = task_create(as, name);
-
 
740
    if (task == NULL) {
-
 
741
        free(kernel_uarg);
-
 
742
        as_destroy(as);
-
 
743
        return NULL;
-
 
744
    }
-
 
745
   
-
 
746
    /*
-
 
747
     * Create the main thread.
-
 
748
     */
-
 
749
    return thread_create(uinit, kernel_uarg, task, THREAD_FLAG_USPACE,
-
 
750
        "uinit", false);
-
 
751
}
-
 
752
 
-
 
753
 
679
/** Update accounting of current thread.
754
/** Update accounting of current thread.
680
 *
755
 *
681
 * Note that thread_lock on THREAD must be already held and
756
 * Note that thread_lock on THREAD must be already held and
682
 * interrupts must be already disabled.
757
 * interrupts must be already disabled.
683
 *
758
 *