Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/proc/thread.c

    r1b20da0 ra35b458  
    122122        void *arg = THREAD->thread_arg;
    123123        THREAD->last_cycle = get_cycle();
    124        
     124
    125125        /* This is where each thread wakes up after its creation */
    126126        irq_spinlock_unlock(&THREAD->lock, false);
    127127        interrupts_enable();
    128        
     128
    129129        f(arg);
    130        
     130
    131131        /* Accumulate accounting to the task */
    132132        irq_spinlock_lock(&THREAD->lock, true);
     
    137137                uint64_t kcycles = THREAD->kcycles;
    138138                THREAD->kcycles = 0;
    139                
     139
    140140                irq_spinlock_pass(&THREAD->lock, &TASK->lock);
    141141                TASK->ucycles += ucycles;
     
    144144        } else
    145145                irq_spinlock_unlock(&THREAD->lock, true);
    146        
     146
    147147        thread_exit();
    148        
     148
    149149        /* Not reached */
    150150}
     
    156156{
    157157        thread_t *thread = (thread_t *) obj;
    158        
     158
    159159        irq_spinlock_initialize(&thread->lock, "thread_t_lock");
    160160        link_initialize(&thread->rq_link);
    161161        link_initialize(&thread->wq_link);
    162162        link_initialize(&thread->th_link);
    163        
     163
    164164        /* call the architecture-specific part of the constructor */
    165165        thr_constructor_arch(thread);
    166        
     166
    167167#ifdef CONFIG_FPU
    168168#ifdef CONFIG_FPU_LAZY
     
    174174#endif /* CONFIG_FPU_LAZY */
    175175#endif /* CONFIG_FPU */
    176        
     176
    177177        /*
    178178         * Allocate the kernel stack from the low-memory to prevent an infinite
     
    193193        kmflags |= FRAME_LOWMEM;
    194194        kmflags &= ~FRAME_HIGHMEM;
    195        
     195
    196196        uintptr_t stack_phys =
    197197            frame_alloc(STACK_FRAMES, kmflags, STACK_SIZE - 1);
     
    203203                return ENOMEM;
    204204        }
    205        
     205
    206206        thread->kstack = (uint8_t *) PA2KA(stack_phys);
    207        
     207
    208208#ifdef CONFIG_UDEBUG
    209209        mutex_initialize(&thread->udebug.lock, MUTEX_PASSIVE);
    210210#endif
    211        
     211
    212212        return EOK;
    213213}
     
    217217{
    218218        thread_t *thread = (thread_t *) obj;
    219        
     219
    220220        /* call the architecture-specific part of the destructor */
    221221        thr_destructor_arch(thread);
    222        
     222
    223223        frame_free(KA2PA(thread->kstack), STACK_FRAMES);
    224        
     224
    225225#ifdef CONFIG_FPU
    226226        if (thread->saved_fpu_context)
    227227                slab_free(fpu_context_cache, thread->saved_fpu_context);
    228228#endif
    229        
     229
    230230        return STACK_FRAMES;  /* number of frames freed */
    231231}
     
    239239{
    240240        THREAD = NULL;
    241        
     241
    242242        atomic_set(&nrdy, 0);
    243243        thread_cache = slab_cache_create("thread_t", sizeof(thread_t), 0,
    244244            thr_constructor, thr_destructor, 0);
    245        
     245
    246246#ifdef CONFIG_FPU
    247247        fpu_context_cache = slab_cache_create("fpu_context_t",
    248248            sizeof(fpu_context_t), FPU_CONTEXT_ALIGN, NULL, NULL, 0);
    249249#endif
    250        
     250
    251251        avltree_create(&threads_tree);
    252252}
     
    282282{
    283283        irq_spinlock_lock(&thread->lock, true);
    284        
     284
    285285        assert(thread->state != Ready);
    286286
    287287        before_thread_is_ready(thread);
    288        
     288
    289289        int i = (thread->priority < RQ_COUNT - 1) ?
    290290            ++thread->priority : thread->priority;
     
    305305                cpu = CPU;
    306306        }
    307        
     307
    308308        thread->state = Ready;
    309        
     309
    310310        irq_spinlock_pass(&thread->lock, &(cpu->rq[i].lock));
    311        
     311
    312312        /*
    313313         * Append thread to respective ready queue
    314314         * on respective processor.
    315315         */
    316        
     316
    317317        list_append(&thread->rq_link, &cpu->rq[i].rq);
    318318        cpu->rq[i].n++;
    319319        irq_spinlock_unlock(&(cpu->rq[i].lock), true);
    320        
     320
    321321        atomic_inc(&nrdy);
    322322        atomic_inc(&cpu->nrdy);
     
    344344        if (!thread)
    345345                return NULL;
    346        
     346
    347347        /* Not needed, but good for debugging */
    348348        memsetb(thread->kstack, STACK_SIZE, 0);
    349        
     349
    350350        irq_spinlock_lock(&tidlock, true);
    351351        thread->tid = ++last_tid;
    352352        irq_spinlock_unlock(&tidlock, true);
    353        
     353
    354354        context_save(&thread->saved_context);
    355355        context_set(&thread->saved_context, FADDR(cushion),
    356356            (uintptr_t) thread->kstack, STACK_SIZE);
    357        
     357
    358358        the_initialize((the_t *) thread->kstack);
    359        
     359
    360360        ipl_t ipl = interrupts_disable();
    361361        thread->saved_context.ipl = interrupts_read();
    362362        interrupts_restore(ipl);
    363        
     363
    364364        str_cpy(thread->name, THREAD_NAME_BUFLEN, name);
    365        
     365
    366366        thread->thread_code = func;
    367367        thread->thread_arg = arg;
     
    377377        thread->uspace =
    378378            ((flags & THREAD_FLAG_USPACE) == THREAD_FLAG_USPACE);
    379        
     379
    380380        thread->nomigrate = 0;
    381381        thread->state = Entering;
    382        
     382
    383383        timeout_initialize(&thread->sleep_timeout);
    384384        thread->sleep_interruptible = false;
    385385        thread->sleep_queue = NULL;
    386386        thread->timeout_pending = false;
    387        
     387
    388388        thread->in_copy_from_uspace = false;
    389389        thread->in_copy_to_uspace = false;
    390        
     390
    391391        thread->interrupted = false;
    392392        thread->detached = false;
    393393        waitq_initialize(&thread->join_wq);
    394        
     394
    395395        thread->task = task;
    396        
     396
    397397        thread->workq = NULL;
    398        
     398
    399399        thread->fpu_context_exists = false;
    400400        thread->fpu_context_engaged = false;
    401        
     401
    402402        avltree_node_initialize(&thread->threads_tree_node);
    403403        thread->threads_tree_node.key = (uintptr_t) thread;
    404        
     404
    405405#ifdef CONFIG_UDEBUG
    406406        /* Initialize debugging stuff */
     
    408408        udebug_thread_initialize(&thread->udebug);
    409409#endif
    410        
     410
    411411        /* Might depend on previous initialization */
    412412        thread_create_arch(thread);
    413        
     413
    414414        rcu_thread_init(thread);
    415        
     415
    416416        if ((flags & THREAD_FLAG_NOATTACH) != THREAD_FLAG_NOATTACH)
    417417                thread_attach(thread, task);
    418        
     418
    419419        return thread;
    420420}
     
    435435        assert(thread->task);
    436436        assert(thread->cpu);
    437        
     437
    438438        irq_spinlock_lock(&thread->cpu->lock, false);
    439439        if (thread->cpu->fpu_owner == thread)
    440440                thread->cpu->fpu_owner = NULL;
    441441        irq_spinlock_unlock(&thread->cpu->lock, false);
    442        
     442
    443443        irq_spinlock_pass(&thread->lock, &threads_lock);
    444        
     444
    445445        avltree_delete(&threads_tree, &thread->threads_tree_node);
    446        
     446
    447447        irq_spinlock_pass(&threads_lock, &thread->task->lock);
    448        
     448
    449449        /*
    450450         * Detach from the containing task.
     
    452452        list_remove(&thread->th_link);
    453453        irq_spinlock_unlock(&thread->task->lock, irq_res);
    454        
     454
    455455        /*
    456456         * Drop the reference to the containing task.
     
    475475         */
    476476        irq_spinlock_lock(&task->lock, true);
    477        
     477
    478478        /* Hold a reference to the task. */
    479479        task_hold(task);
    480        
     480
    481481        /* Must not count kbox thread into lifecount */
    482482        if (thread->uspace)
    483483                atomic_inc(&task->lifecount);
    484        
     484
    485485        list_append(&thread->th_link, &task->threads);
    486        
     486
    487487        irq_spinlock_pass(&task->lock, &threads_lock);
    488        
     488
    489489        /*
    490490         * Register this thread in the system-wide list.
     
    506506                /* Generate udebug THREAD_E event */
    507507                udebug_thread_e_event();
    508                
     508
    509509                /*
    510510                 * This thread will not execute any code or system calls from
     
    527527                }
    528528        }
    529        
     529
    530530restart:
    531531        irq_spinlock_lock(&THREAD->lock, true);
     
    535535                goto restart;
    536536        }
    537        
     537
    538538        THREAD->state = Exiting;
    539539        irq_spinlock_unlock(&THREAD->lock, true);
    540        
     540
    541541        scheduler();
    542        
     542
    543543        /* Not reached */
    544544        while (true);
     
    562562{
    563563        assert(thread != NULL);
    564        
     564
    565565        irq_spinlock_lock(&thread->lock, true);
    566        
     566
    567567        thread->interrupted = true;
    568568        bool sleeping = (thread->state == Sleeping);
    569        
     569
    570570        irq_spinlock_unlock(&thread->lock, true);
    571        
     571
    572572        if (sleeping)
    573573                waitq_interrupt_sleep(thread);
     
    583583{
    584584        assert(thread != NULL);
    585        
     585
    586586        bool interrupted;
    587        
     587
    588588        irq_spinlock_lock(&thread->lock, true);
    589589        interrupted = thread->interrupted;
    590590        irq_spinlock_unlock(&thread->lock, true);
    591        
     591
    592592        return interrupted;
    593593}
     
    597597{
    598598        assert(THREAD);
    599        
     599
    600600        THREAD->nomigrate++;
    601601}
     
    606606        assert(THREAD);
    607607        assert(THREAD->nomigrate > 0);
    608        
     608
    609609        if (THREAD->nomigrate > 0)
    610610                THREAD->nomigrate--;
     
    624624        while (sec > 0) {
    625625                uint32_t period = (sec > 1000) ? 1000 : sec;
    626                
     626
    627627                thread_usleep(period * 1000000);
    628628                sec -= period;
     
    643643        if (thread == THREAD)
    644644                return EINVAL;
    645        
     645
    646646        /*
    647647         * Since thread join can only be called once on an undetached thread,
    648648         * the thread pointer is guaranteed to be still valid.
    649649         */
    650        
     650
    651651        irq_spinlock_lock(&thread->lock, true);
    652652        assert(!thread->detached);
    653653        irq_spinlock_unlock(&thread->lock, true);
    654        
     654
    655655        return waitq_sleep_timeout(&thread->join_wq, usec, flags, NULL);
    656656}
     
    672672        irq_spinlock_lock(&thread->lock, true);
    673673        assert(!thread->detached);
    674        
     674
    675675        if (thread->state == Lingering) {
    676676                /*
     
    683683                thread->detached = true;
    684684        }
    685        
     685
    686686        irq_spinlock_unlock(&thread->lock, true);
    687687}
     
    697697{
    698698        waitq_t wq;
    699        
     699
    700700        waitq_initialize(&wq);
    701        
     701
    702702        (void) waitq_sleep_timeout(&wq, usec, SYNCH_FLAGS_NON_BLOCKING, NULL);
    703703}
     
    707707        bool *additional = (bool *) arg;
    708708        thread_t *thread = avltree_get_instance(node, thread_t, threads_tree_node);
    709        
     709
    710710        uint64_t ucycles, kcycles;
    711711        char usuffix, ksuffix;
    712712        order_suffix(thread->ucycles, &ucycles, &usuffix);
    713713        order_suffix(thread->kcycles, &kcycles, &ksuffix);
    714        
     714
    715715        char *name;
    716716        if (str_cmp(thread->name, "uinit") == 0)
     
    718718        else
    719719                name = thread->name;
    720        
     720
    721721#ifdef __32_BITS__
    722722        if (*additional)
     
    729729                    thread->task, thread->task->container);
    730730#endif
    731        
     731
    732732#ifdef __64_BITS__
    733733        if (*additional)
     
    741741                    thread->task, thread->task->container);
    742742#endif
    743        
     743
    744744        if (*additional) {
    745745                if (thread->cpu)
     
    747747                else
    748748                        printf("none ");
    749                
     749
    750750                if (thread->state == Sleeping) {
    751751#ifdef __32_BITS__
    752752                        printf(" %10p", thread->sleep_queue);
    753753#endif
    754                        
     754
    755755#ifdef __64_BITS__
    756756                        printf(" %18p", thread->sleep_queue);
    757757#endif
    758758                }
    759                
     759
    760760                printf("\n");
    761761        }
    762        
     762
    763763        return true;
    764764}
     
    773773        /* Messing with thread structures, avoid deadlock */
    774774        irq_spinlock_lock(&threads_lock, true);
    775        
     775
    776776#ifdef __32_BITS__
    777777        if (additional)
     
    782782                    " [ctn]\n");
    783783#endif
    784        
     784
    785785#ifdef __64_BITS__
    786786        if (additional) {
     
    791791                    " [task            ] [ctn]\n");
    792792#endif
    793        
     793
    794794        avltree_walk(&threads_tree, thread_walker, &additional);
    795        
     795
    796796        irq_spinlock_unlock(&threads_lock, true);
    797797}
     
    814814        avltree_node_t *node =
    815815            avltree_search(&threads_tree, (avltree_key_t) ((uintptr_t) thread));
    816        
     816
    817817        return node != NULL;
    818818}
     
    832832        assert(interrupts_disabled());
    833833        assert(irq_spinlock_locked(&THREAD->lock));
    834        
     834
    835835        if (user)
    836836                THREAD->ucycles += time - THREAD->last_cycle;
    837837        else
    838838                THREAD->kcycles += time - THREAD->last_cycle;
    839        
     839
    840840        THREAD->last_cycle = time;
    841841}
     
    846846            (thread_t *) avltree_get_instance(node, thread_t, threads_tree_node);
    847847        thread_iterator_t *iterator = (thread_iterator_t *) arg;
    848        
     848
    849849        if (thread->tid == iterator->thread_id) {
    850850                iterator->thread = thread;
    851851                return false;
    852852        }
    853        
     853
    854854        return true;
    855855}
     
    869869        assert(interrupts_disabled());
    870870        assert(irq_spinlock_locked(&threads_lock));
    871        
     871
    872872        thread_iterator_t iterator;
    873        
     873
    874874        iterator.thread_id = thread_id;
    875875        iterator.thread = NULL;
    876        
     876
    877877        avltree_walk(&threads_tree, thread_search_walker, (void *) &iterator);
    878        
     878
    879879        return iterator.thread;
    880880}
     
    885885{
    886886        irq_spinlock_lock(&threads_lock, true);
    887        
     887
    888888        thread_t *thread = thread_find_by_id(thread_id);
    889889        if (thread == NULL) {
     
    892892                return;
    893893        }
    894        
     894
    895895        irq_spinlock_lock(&thread->lock, false);
    896        
     896
    897897        /*
    898898         * Schedule a stack trace to be printed
     
    906906         * is probably justifiable.
    907907         */
    908        
     908
    909909        bool sleeping = false;
    910910        istate_t *istate = thread->udebug.uspace_state;
     
    916916        } else
    917917                printf("Thread interrupt state not available.\n");
    918        
     918
    919919        irq_spinlock_unlock(&thread->lock, false);
    920        
     920
    921921        if (sleeping)
    922922                waitq_interrupt_sleep(thread);
    923        
     923
    924924        irq_spinlock_unlock(&threads_lock, true);
    925925}
     
    935935        if (name_len > THREAD_NAME_BUFLEN - 1)
    936936                name_len = THREAD_NAME_BUFLEN - 1;
    937        
     937
    938938        char namebuf[THREAD_NAME_BUFLEN];
    939939        errno_t rc = copy_from_uspace(namebuf, uspace_name, name_len);
    940940        if (rc != EOK)
    941941                return (sys_errno_t) rc;
    942        
     942
    943943        namebuf[name_len] = 0;
    944        
     944
    945945        /*
    946946         * In case of failure, kernel_uarg will be deallocated in this function.
     
    949949        uspace_arg_t *kernel_uarg =
    950950            (uspace_arg_t *) malloc(sizeof(uspace_arg_t), 0);
    951        
     951
    952952        rc = copy_from_uspace(kernel_uarg, uspace_uarg, sizeof(uspace_arg_t));
    953953        if (rc != EOK) {
     
    955955                return (sys_errno_t) rc;
    956956        }
    957        
     957
    958958        thread_t *thread = thread_create(uinit, kernel_uarg, TASK,
    959959            THREAD_FLAG_USPACE | THREAD_FLAG_NOATTACH, namebuf);
     
    968968                                 * creation now.
    969969                                 */
    970                                
     970
    971971                                /*
    972972                                 * The new thread structure is initialized, but
     
    976976                                slab_free(thread_cache, thread);
    977977                                free(kernel_uarg);
    978                                
     978
    979979                                return (sys_errno_t) rc;
    980980                         }
    981981                }
    982                
     982
    983983#ifdef CONFIG_UDEBUG
    984984                /*
     
    994994#endif
    995995                thread_ready(thread);
    996                
     996
    997997                return 0;
    998998        } else
    999999                free(kernel_uarg);
    1000        
     1000
    10011001        return (sys_errno_t) ENOMEM;
    10021002}
Note: See TracChangeset for help on using the changeset viewer.