Changeset da1bafb in mainline for kernel/generic/src/proc


Ignore:
Timestamp:
2010-05-24T18:57:31Z (15 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0095368
Parents:
666f492
Message:

major code revision

  • replace spinlocks taken with interrupts disabled with irq_spinlocks
  • change spacing (not indendation) to be tab-size independent
  • use unsigned integer types where appropriate (especially bit flags)
  • visual separation
  • remove argument names in function prototypes
  • string changes
  • correct some formating directives
  • replace various cryptic single-character variables (t, a, m, c, b, etc.) with proper identifiers (thread, task, timeout, as, itm, itc, etc.)
  • unify some assembler constructs
  • unused page table levels are now optimized out in compile time
  • replace several ints (with boolean semantics) with bools
  • use specifically sized types instead of generic types where appropriate (size_t, uint32_t, btree_key_t)
  • improve comments
  • split asserts with conjuction into multiple independent asserts
Location:
kernel/generic/src/proc
Files:
3 edited

Legend:

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

    r666f492 rda1bafb  
    3333/**
    3434 * @file
    35  * @brief       Scheduler and load balancing.
     35 * @brief Scheduler and load balancing.
    3636 *
    3737 * This file contains the scheduler and kcpulb kernel thread which
     
    6868static void scheduler_separated_stack(void);
    6969
    70 atomic_t nrdy;  /**< Number of ready threads in the system. */
     70atomic_t nrdy;  /**< Number of ready threads in the system. */
    7171
    7272/** Carry out actions before new task runs. */
     
    8989        before_thread_runs_arch();
    9090#ifdef CONFIG_FPU_LAZY
    91         if(THREAD == CPU->fpu_owner) 
     91        if(THREAD == CPU->fpu_owner)
    9292                fpu_enable();
    9393        else
    94                 fpu_disable(); 
     94                fpu_disable();
    9595#else
    9696        fpu_enable();
     
    123123restart:
    124124        fpu_enable();
    125         spinlock_lock(&CPU->lock);
    126 
     125        irq_spinlock_lock(&CPU->lock, false);
     126       
    127127        /* Save old context */
    128         if (CPU->fpu_owner != NULL) { 
    129                 spinlock_lock(&CPU->fpu_owner->lock);
     128        if (CPU->fpu_owner != NULL) {
     129                irq_spinlock_lock(&CPU->fpu_owner->lock, false);
    130130                fpu_context_save(CPU->fpu_owner->saved_fpu_context);
    131                 /* don't prevent migration */
     131               
     132                /* Don't prevent migration */
    132133                CPU->fpu_owner->fpu_context_engaged = 0;
    133                 spinlock_unlock(&CPU->fpu_owner->lock);
     134                irq_spinlock_unlock(&CPU->fpu_owner->lock, false);
    134135                CPU->fpu_owner = NULL;
    135136        }
    136 
    137         spinlock_lock(&THREAD->lock);
     137       
     138        irq_spinlock_lock(&THREAD->lock, false);
    138139        if (THREAD->fpu_context_exists) {
    139140                fpu_context_restore(THREAD->saved_fpu_context);
     
    142143                if (!THREAD->saved_fpu_context) {
    143144                        /* Might sleep */
    144                         spinlock_unlock(&THREAD->lock);
    145                         spinlock_unlock(&CPU->lock);
     145                        irq_spinlock_unlock(&THREAD->lock, false);
     146                        irq_spinlock_unlock(&CPU->lock, false);
    146147                        THREAD->saved_fpu_context =
    147148                            (fpu_context_t *) slab_alloc(fpu_context_slab, 0);
     149                       
    148150                        /* We may have switched CPUs during slab_alloc */
    149                         goto restart; 
     151                        goto restart;
    150152                }
    151153                fpu_init();
    152154                THREAD->fpu_context_exists = 1;
    153155        }
     156       
    154157        CPU->fpu_owner = THREAD;
    155158        THREAD->fpu_context_engaged = 1;
    156         spinlock_unlock(&THREAD->lock);
    157 
    158         spinlock_unlock(&CPU->lock);
    159 }
    160 #endif
     159        irq_spinlock_unlock(&THREAD->lock, false);
     160       
     161        irq_spinlock_unlock(&CPU->lock, false);
     162}
     163#endif /* CONFIG_FPU_LAZY */
    161164
    162165/** Initialize scheduler
     
    180183static thread_t *find_best_thread(void)
    181184{
    182         thread_t *t;
    183         runq_t *r;
    184         int i;
    185 
    186185        ASSERT(CPU != NULL);
    187 
     186       
    188187loop:
    189188       
     
    194193                 * This improves energy saving and hyperthreading.
    195194                 */
    196 
     195               
    197196                 /* Mark CPU as it was idle this clock tick */
    198                  spinlock_lock(&CPU->lock);
    199                  CPU->idle = true;
    200                  spinlock_unlock(&CPU->lock);
    201 
    202                  interrupts_enable();
    203                  /*
     197                irq_spinlock_lock(&CPU->lock, false);
     198                CPU->idle = true;
     199                irq_spinlock_unlock(&CPU->lock, false);
     200               
     201                interrupts_enable();
     202                /*
    204203                 * An interrupt might occur right now and wake up a thread.
    205204                 * In such case, the CPU will continue to go to sleep
    206205                 * even though there is a runnable thread.
    207206                 */
    208                  cpu_sleep();
    209                  interrupts_disable();
    210                  goto loop;
    211         }
    212        
     207                cpu_sleep();
     208                interrupts_disable();
     209                goto loop;
     210        }
     211       
     212        unsigned int i;
    213213        for (i = 0; i < RQ_COUNT; i++) {
    214                 r = &CPU->rq[i];
    215                 spinlock_lock(&r->lock);
    216                 if (r->n == 0) {
     214                irq_spinlock_lock(&(CPU->rq[i].lock), false);
     215                if (CPU->rq[i].n == 0) {
    217216                        /*
    218217                         * If this queue is empty, try a lower-priority queue.
    219218                         */
    220                         spinlock_unlock(&r->lock);
     219                        irq_spinlock_unlock(&(CPU->rq[i].lock), false);
    221220                        continue;
    222221                }
    223 
     222               
    224223                atomic_dec(&CPU->nrdy);
    225224                atomic_dec(&nrdy);
    226                 r->n--;
    227 
     225                CPU->rq[i].n--;
     226               
    228227                /*
    229228                 * Take the first thread from the queue.
    230229                 */
    231                 t = list_get_instance(r->rq_head.next, thread_t, rq_link);
    232                 list_remove(&t->rq_link);
    233 
    234                 spinlock_unlock(&r->lock);
    235 
    236                 spinlock_lock(&t->lock);
    237                 t->cpu = CPU;
    238 
    239                 t->ticks = us2ticks((i + 1) * 10000);
    240                 t->priority = i;        /* correct rq index */
    241 
     230                thread_t *thread =
     231                    list_get_instance(CPU->rq[i].rq_head.next, thread_t, rq_link);
     232                list_remove(&thread->rq_link);
     233               
     234                irq_spinlock_pass(&(CPU->rq[i].lock), &thread->lock);
     235               
     236                thread->cpu = CPU;
     237                thread->ticks = us2ticks((i + 1) * 10000);
     238                thread->priority = i;  /* Correct rq index */
     239               
    242240                /*
    243241                 * Clear the THREAD_FLAG_STOLEN flag so that t can be migrated
    244242                 * when load balancing needs emerge.
    245243                 */
    246                 t->flags &= ~THREAD_FLAG_STOLEN;
    247                 spinlock_unlock(&t->lock);
    248 
    249                 return t;
    250         }
     244                thread->flags &= ~THREAD_FLAG_STOLEN;
     245                irq_spinlock_unlock(&thread->lock, false);
     246               
     247                return thread;
     248        }
     249       
    251250        goto loop;
    252 
    253251}
    254252
     
    267265{
    268266        link_t head;
    269         runq_t *r;
    270         int i, n;
    271 
     267       
    272268        list_initialize(&head);
    273         spinlock_lock(&CPU->lock);
     269        irq_spinlock_lock(&CPU->lock, false);
     270       
    274271        if (CPU->needs_relink > NEEDS_RELINK_MAX) {
     272                int i;
    275273                for (i = start; i < RQ_COUNT - 1; i++) {
    276                         /* remember and empty rq[i + 1] */
    277                         r = &CPU->rq[i + 1];
    278                         spinlock_lock(&r->lock);
    279                         list_concat(&head, &r->rq_head);
    280                         n = r->n;
    281                         r->n = 0;
    282                         spinlock_unlock(&r->lock);
    283                
    284                         /* append rq[i + 1] to rq[i] */
    285                         r = &CPU->rq[i];
    286                         spinlock_lock(&r->lock);
    287                         list_concat(&r->rq_head, &head);
    288                         r->n += n;
    289                         spinlock_unlock(&r->lock);
     274                        /* Remember and empty rq[i + 1] */
     275                       
     276                        irq_spinlock_lock(&CPU->rq[i + 1].lock, false);
     277                        list_concat(&head, &CPU->rq[i + 1].rq_head);
     278                        size_t n = CPU->rq[i + 1].n;
     279                        CPU->rq[i + 1].n = 0;
     280                        irq_spinlock_unlock(&CPU->rq[i + 1].lock, false);
     281                       
     282                        /* Append rq[i + 1] to rq[i] */
     283                       
     284                        irq_spinlock_lock(&CPU->rq[i].lock, false);
     285                        list_concat(&CPU->rq[i].rq_head, &head);
     286                        CPU->rq[i].n += n;
     287                        irq_spinlock_unlock(&CPU->rq[i].lock, false);
    290288                }
     289               
    291290                CPU->needs_relink = 0;
    292291        }
    293         spinlock_unlock(&CPU->lock);
    294 
     292       
     293        irq_spinlock_unlock(&CPU->lock, false);
    295294}
    296295
     
    305304{
    306305        volatile ipl_t ipl;
    307 
     306       
    308307        ASSERT(CPU != NULL);
    309 
     308       
    310309        ipl = interrupts_disable();
    311 
     310       
    312311        if (atomic_get(&haltstate))
    313312                halt();
    314313       
    315314        if (THREAD) {
    316                 spinlock_lock(&THREAD->lock);
     315                irq_spinlock_lock(&THREAD->lock, false);
    317316               
    318317                /* Update thread kernel accounting */
     
    330329                        THREAD->last_cycle = get_cycle();
    331330                       
    332                         spinlock_unlock(&THREAD->lock);
     331                        irq_spinlock_unlock(&THREAD->lock, false);
    333332                        interrupts_restore(THREAD->saved_context.ipl);
    334333                       
    335334                        return;
    336335                }
    337 
     336               
    338337                /*
    339338                 * Interrupt priority level of preempted thread is recorded
    340339                 * here to facilitate scheduler() invocations from
    341                  * interrupts_disable()'d code (e.g. waitq_sleep_timeout()).
     340                 * interrupts_disable()'d code (e.g. waitq_sleep_timeout()).
     341                 *
    342342                 */
    343343                THREAD->saved_context.ipl = ipl;
    344344        }
    345 
     345       
    346346        /*
    347347         * Through the 'THE' structure, we keep track of THREAD, TASK, CPU, VM
    348348         * and preemption counter. At this point THE could be coming either
    349349         * from THREAD's or CPU's stack.
     350         *
    350351         */
    351352        the_copy(THE, (the_t *) CPU->stack);
    352 
     353       
    353354        /*
    354355         * We may not keep the old stack.
     
    362363         * Therefore the scheduler() function continues in
    363364         * scheduler_separated_stack().
     365         *
    364366         */
    365367        context_save(&CPU->saved_context);
     
    367369            (uintptr_t) CPU->stack, CPU_STACK_SIZE);
    368370        context_restore(&CPU->saved_context);
    369         /* not reached */
     371       
     372        /* Not reached */
    370373}
    371374
     
    377380 *
    378381 * Assume THREAD->lock is held.
     382 *
    379383 */
    380384void scheduler_separated_stack(void)
    381385{
    382         int priority;
    383386        DEADLOCK_PROBE_INIT(p_joinwq);
    384387        task_t *old_task = TASK;
    385388        as_t *old_as = AS;
    386 
     389       
    387390        ASSERT(CPU != NULL);
    388391       
     
    391394         * possible destruction should thread_destroy() be called on this or any
    392395         * other processor while the scheduler is still using them.
     396         *
    393397         */
    394398        if (old_task)
    395399                task_hold(old_task);
     400       
    396401        if (old_as)
    397402                as_hold(old_as);
    398 
     403       
    399404        if (THREAD) {
    400                 /* must be run after the switch to scheduler stack */
     405                /* Must be run after the switch to scheduler stack */
    401406                after_thread_ran();
    402 
     407               
    403408                switch (THREAD->state) {
    404409                case Running:
    405                         spinlock_unlock(&THREAD->lock);
     410                        irq_spinlock_unlock(&THREAD->lock, false);
    406411                        thread_ready(THREAD);
    407412                        break;
    408 
     413               
    409414                case Exiting:
    410415repeat:
    411416                        if (THREAD->detached) {
    412                                 thread_destroy(THREAD);
     417                                thread_destroy(THREAD, false);
    413418                        } else {
    414419                                /*
    415420                                 * The thread structure is kept allocated until
    416421                                 * somebody calls thread_detach() on it.
     422                                 *
    417423                                 */
    418                                 if (!spinlock_trylock(&THREAD->join_wq.lock)) {
     424                                if (!irq_spinlock_trylock(&THREAD->join_wq.lock)) {
    419425                                        /*
    420426                                         * Avoid deadlock.
     427                                         *
    421428                                         */
    422                                         spinlock_unlock(&THREAD->lock);
     429                                        irq_spinlock_unlock(&THREAD->lock, false);
    423430                                        delay(HZ);
    424                                         spinlock_lock(&THREAD->lock);
     431                                        irq_spinlock_lock(&THREAD->lock, false);
    425432                                        DEADLOCK_PROBE(p_joinwq,
    426433                                            DEADLOCK_THRESHOLD);
     
    429436                                _waitq_wakeup_unsafe(&THREAD->join_wq,
    430437                                    WAKEUP_FIRST);
    431                                 spinlock_unlock(&THREAD->join_wq.lock);
     438                                irq_spinlock_unlock(&THREAD->join_wq.lock, false);
    432439                               
    433440                                THREAD->state = Lingering;
    434                                 spinlock_unlock(&THREAD->lock);
     441                                irq_spinlock_unlock(&THREAD->lock, false);
    435442                        }
    436443                        break;
     
    439446                        /*
    440447                         * Prefer the thread after it's woken up.
     448                         *
    441449                         */
    442450                        THREAD->priority = -1;
    443 
     451                       
    444452                        /*
    445453                         * We need to release wq->lock which we locked in
    446454                         * waitq_sleep(). Address of wq->lock is kept in
    447455                         * THREAD->sleep_queue.
     456                         *
    448457                         */
    449                         spinlock_unlock(&THREAD->sleep_queue->lock);
    450 
     458                        irq_spinlock_unlock(&THREAD->sleep_queue->lock, false);
     459                       
    451460                        /*
    452461                         * Check for possible requests for out-of-context
    453462                         * invocation.
     463                         *
    454464                         */
    455465                        if (THREAD->call_me) {
     
    458468                                THREAD->call_me_with = NULL;
    459469                        }
    460 
    461                         spinlock_unlock(&THREAD->lock);
    462 
     470                       
     471                        irq_spinlock_unlock(&THREAD->lock, false);
     472                       
    463473                        break;
    464 
     474               
    465475                default:
    466476                        /*
    467477                         * Entering state is unexpected.
     478                         *
    468479                         */
    469480                        panic("tid%" PRIu64 ": unexpected state %s.",
     
    471482                        break;
    472483                }
    473 
     484               
    474485                THREAD = NULL;
    475486        }
    476 
     487       
    477488        THREAD = find_best_thread();
    478489       
    479         spinlock_lock(&THREAD->lock);
    480         priority = THREAD->priority;
    481         spinlock_unlock(&THREAD->lock);
    482 
    483         relink_rq(priority);           
    484 
     490        irq_spinlock_lock(&THREAD->lock, false);
     491        int priority = THREAD->priority;
     492        irq_spinlock_unlock(&THREAD->lock, false);
     493       
     494        relink_rq(priority);
     495       
    485496        /*
    486497         * If both the old and the new task are the same, lots of work is
    487498         * avoided.
     499         *
    488500         */
    489501        if (TASK != THREAD->task) {
     
    493505                 * Note that it is possible for two tasks to share one address
    494506                 * space.
     507                 (
    495508                 */
    496509                if (old_as != new_as) {
     
    498511                         * Both tasks and address spaces are different.
    499512                         * Replace the old one with the new one.
     513                         *
    500514                         */
    501515                        as_switch(old_as, new_as);
    502516                }
    503 
     517               
    504518                TASK = THREAD->task;
    505519                before_task_runs();
    506520        }
    507 
     521       
    508522        if (old_task)
    509523                task_release(old_task);
     524       
    510525        if (old_as)
    511526                as_release(old_as);
    512527       
    513         spinlock_lock(&THREAD->lock);   
     528        irq_spinlock_lock(&THREAD->lock, false);
    514529        THREAD->state = Running;
    515 
     530       
    516531#ifdef SCHEDULER_VERBOSE
    517532        printf("cpu%u: tid %" PRIu64 " (priority=%d, ticks=%" PRIu64
    518533            ", nrdy=%ld)\n", CPU->id, THREAD->tid, THREAD->priority,
    519534            THREAD->ticks, atomic_get(&CPU->nrdy));
    520 #endif 
    521 
     535#endif
     536       
    522537        /*
    523538         * Some architectures provide late kernel PA2KA(identity)
     
    527542         * necessary, is to be mapped in before_thread_runs(). This
    528543         * function must be executed before the switch to the new stack.
     544         *
    529545         */
    530546        before_thread_runs();
    531 
     547       
    532548        /*
    533549         * Copy the knowledge of CPU, TASK, THREAD and preemption counter to
    534550         * thread's stack.
     551         *
    535552         */
    536553        the_copy(THE, (the_t *) THREAD->kstack);
    537554       
    538555        context_restore(&THREAD->saved_context);
    539         /* not reached */
     556       
     557        /* Not reached */
    540558}
    541559
     
    551569void kcpulb(void *arg)
    552570{
    553         thread_t *t;
    554         int count;
    555571        atomic_count_t average;
    556         unsigned int i;
    557         int j;
    558         int k = 0;
    559         ipl_t ipl;
    560 
     572        atomic_count_t rdy;
     573       
    561574        /*
    562575         * Detach kcpulb as nobody will call thread_join_timeout() on it.
     
    569582         */
    570583        thread_sleep(1);
    571 
     584       
    572585not_satisfied:
    573586        /*
     
    575588         * other CPU's. Note that situation can have changed between two
    576589         * passes. Each time get the most up to date counts.
     590         *
    577591         */
    578592        average = atomic_get(&nrdy) / config.cpu_active + 1;
    579         count = average - atomic_get(&CPU->nrdy);
    580 
    581         if (count <= 0)
     593        rdy = atomic_get(&CPU->nrdy);
     594       
     595        if (average <= rdy)
    582596                goto satisfied;
    583 
     597       
     598        atomic_count_t count = average - rdy;
     599       
    584600        /*
    585601         * Searching least priority queues on all CPU's first and most priority
    586602         * queues on all CPU's last.
    587          */
    588         for (j = RQ_COUNT - 1; j >= 0; j--) {
    589                 for (i = 0; i < config.cpu_active; i++) {
    590                         link_t *l;
    591                         runq_t *r;
    592                         cpu_t *cpu;
    593 
    594                         cpu = &cpus[(i + k) % config.cpu_active];
    595 
     603         *
     604         */
     605        size_t acpu;
     606        size_t acpu_bias = 0;
     607        int rq;
     608       
     609        for (rq = RQ_COUNT - 1; rq >= 0; rq--) {
     610                for (acpu = 0; acpu < config.cpu_active; acpu++) {
     611                        cpu_t *cpu = &cpus[(acpu + acpu_bias) % config.cpu_active];
     612                       
    596613                        /*
    597614                         * Not interested in ourselves.
    598615                         * Doesn't require interrupt disabling for kcpulb has
    599616                         * THREAD_FLAG_WIRED.
     617                         *
    600618                         */
    601619                        if (CPU == cpu)
    602620                                continue;
     621                       
    603622                        if (atomic_get(&cpu->nrdy) <= average)
    604623                                continue;
    605 
    606                         ipl = interrupts_disable();
    607                         r = &cpu->rq[j];
    608                         spinlock_lock(&r->lock);
    609                         if (r->n == 0) {
    610                                 spinlock_unlock(&r->lock);
    611                                 interrupts_restore(ipl);
     624                       
     625                        irq_spinlock_lock(&(cpu->rq[rq].lock), true);
     626                        if (cpu->rq[rq].n == 0) {
     627                                irq_spinlock_unlock(&(cpu->rq[rq].lock), true);
    612628                                continue;
    613629                        }
    614                
    615                         t = NULL;
    616                         l = r->rq_head.prev;    /* search rq from the back */
    617                         while (l != &r->rq_head) {
    618                                 t = list_get_instance(l, thread_t, rq_link);
     630                       
     631                        thread_t *thread = NULL;
     632                       
     633                        /* Search rq from the back */
     634                        link_t *link = cpu->rq[rq].rq_head.prev;
     635                       
     636                        while (link != &(cpu->rq[rq].rq_head)) {
     637                                thread = (thread_t *) list_get_instance(link, thread_t, rq_link);
     638                               
    619639                                /*
    620640                                 * We don't want to steal CPU-wired threads
     
    624644                                 * steal threads whose FPU context is still in
    625645                                 * CPU.
     646                                 *
    626647                                 */
    627                                 spinlock_lock(&t->lock);
    628                                 if ((!(t->flags & (THREAD_FLAG_WIRED |
    629                                     THREAD_FLAG_STOLEN))) &&
    630                                     (!(t->fpu_context_engaged))) {
     648                                irq_spinlock_lock(&thread->lock, false);
     649                               
     650                                if ((!(thread->flags & (THREAD_FLAG_WIRED | THREAD_FLAG_STOLEN)))
     651                                    && (!(thread->fpu_context_engaged))) {
    631652                                        /*
    632                                          * Remove t from r.
     653                                         * Remove thread from ready queue.
    633654                                         */
    634                                         spinlock_unlock(&t->lock);
     655                                        irq_spinlock_unlock(&thread->lock, false);
    635656                                       
    636657                                        atomic_dec(&cpu->nrdy);
    637658                                        atomic_dec(&nrdy);
    638 
    639                                         r->n--;
    640                                         list_remove(&t->rq_link);
    641 
     659                                       
     660                                        cpu->rq[rq].n--;
     661                                        list_remove(&thread->rq_link);
     662                                       
    642663                                        break;
    643664                                }
    644                                 spinlock_unlock(&t->lock);
    645                                 l = l->prev;
    646                                 t = NULL;
     665                               
     666                                irq_spinlock_unlock(&thread->lock, false);
     667                               
     668                                link = link->prev;
     669                                thread = NULL;
    647670                        }
    648                         spinlock_unlock(&r->lock);
    649 
    650                         if (t) {
     671                       
     672                        if (thread) {
    651673                                /*
    652                                  * Ready t on local CPU
     674                                 * Ready thread on local CPU
     675                                 *
    653676                                 */
    654                                 spinlock_lock(&t->lock);
     677                               
     678                                irq_spinlock_pass(&(cpu->rq[rq].lock), &thread->lock);
     679                               
    655680#ifdef KCPULB_VERBOSE
    656681                                printf("kcpulb%u: TID %" PRIu64 " -> cpu%u, "
     
    659684                                    atomic_get(&nrdy) / config.cpu_active);
    660685#endif
    661                                 t->flags |= THREAD_FLAG_STOLEN;
    662                                 t->state = Entering;
    663                                 spinlock_unlock(&t->lock);
    664        
    665                                 thread_ready(t);
    666 
    667                                 interrupts_restore(ipl);
    668        
     686                               
     687                                thread->flags |= THREAD_FLAG_STOLEN;
     688                                thread->state = Entering;
     689                               
     690                                irq_spinlock_unlock(&thread->lock, true);
     691                                thread_ready(thread);
     692                               
    669693                                if (--count == 0)
    670694                                        goto satisfied;
    671                                        
     695                               
    672696                                /*
    673697                                 * We are not satisfied yet, focus on another
    674698                                 * CPU next time.
     699                                 *
    675700                                 */
    676                                 k++;
     701                                acpu_bias++;
    677702                               
    678703                                continue;
    679                         }
    680                         interrupts_restore(ipl);
     704                        } else
     705                                irq_spinlock_unlock(&(cpu->rq[rq].lock), true);
     706                       
    681707                }
    682708        }
    683 
     709       
    684710        if (atomic_get(&CPU->nrdy)) {
    685711                /*
    686712                 * Be a little bit light-weight and let migrated threads run.
     713                 *
    687714                 */
    688715                scheduler();
     
    691718                 * We failed to migrate a single thread.
    692719                 * Give up this turn.
     720                 *
    693721                 */
    694722                goto loop;
    695723        }
    696                
     724       
    697725        goto not_satisfied;
    698 
     726       
    699727satisfied:
    700728        goto loop;
    701729}
    702 
    703730#endif /* CONFIG_SMP */
    704731
    705 
    706 /** Print information about threads & scheduler queues */
     732/** Print information about threads & scheduler queues
     733 *
     734 */
    707735void sched_print_list(void)
    708736{
    709         ipl_t ipl;
    710         unsigned int cpu, i;
    711         runq_t *r;
    712         thread_t *t;
    713         link_t *cur;
    714 
    715         /* We are going to mess with scheduler structures,
    716          * let's not be interrupted */
    717         ipl = interrupts_disable();
     737        size_t cpu;
    718738        for (cpu = 0; cpu < config.cpu_count; cpu++) {
    719 
    720739                if (!cpus[cpu].active)
    721740                        continue;
    722 
    723                 spinlock_lock(&cpus[cpu].lock);
     741               
     742                irq_spinlock_lock(&cpus[cpu].lock, true);
     743               
    724744                printf("cpu%u: address=%p, nrdy=%ld, needs_relink=%" PRIs "\n",
    725745                    cpus[cpu].id, &cpus[cpu], atomic_get(&cpus[cpu].nrdy),
    726746                    cpus[cpu].needs_relink);
    727747               
     748                unsigned int i;
    728749                for (i = 0; i < RQ_COUNT; i++) {
    729                         r = &cpus[cpu].rq[i];
    730                         spinlock_lock(&r->lock);
    731                         if (!r->n) {
    732                                 spinlock_unlock(&r->lock);
     750                        irq_spinlock_lock(&(cpus[cpu].rq[i].lock), false);
     751                        if (cpus[cpu].rq[i].n == 0) {
     752                                irq_spinlock_unlock(&(cpus[cpu].rq[i].lock), false);
    733753                                continue;
    734754                        }
     755                       
    735756                        printf("\trq[%u]: ", i);
    736                         for (cur = r->rq_head.next; cur != &r->rq_head;
    737                                 cur = cur->next) {
    738                                 t = list_get_instance(cur, thread_t, rq_link);
    739                                 printf("%" PRIu64 "(%s) ", t->tid,
    740                                     thread_states[t->state]);
     757                        link_t *cur;
     758                        for (cur = cpus[cpu].rq[i].rq_head.next;
     759                            cur != &(cpus[cpu].rq[i].rq_head);
     760                            cur = cur->next) {
     761                                thread_t *thread = list_get_instance(cur, thread_t, rq_link);
     762                                printf("%" PRIu64 "(%s) ", thread->tid,
     763                                    thread_states[thread->state]);
    741764                        }
    742765                        printf("\n");
    743                         spinlock_unlock(&r->lock);
     766                       
     767                        irq_spinlock_unlock(&(cpus[cpu].rq[i].lock), false);
    744768                }
    745                 spinlock_unlock(&cpus[cpu].lock);
    746         }
    747        
    748         interrupts_restore(ipl);
     769               
     770                irq_spinlock_unlock(&cpus[cpu].lock, true);
     771        }
    749772}
    750773
  • kernel/generic/src/proc/task.c

    r666f492 rda1bafb  
    6060
    6161/** Spinlock protecting the tasks_tree AVL tree. */
    62 SPINLOCK_INITIALIZE(tasks_lock);
     62IRQ_SPINLOCK_INITIALIZE(tasks_lock);
    6363
    6464/** AVL tree of active tasks.
     
    8181/* Forward declarations. */
    8282static void task_kill_internal(task_t *);
    83 static int tsk_constructor(void *, int);
    84 
    85 /** Initialize kernel tasks support. */
     83static int tsk_constructor(void *, unsigned int);
     84
     85/** Initialize kernel tasks support.
     86 *
     87 */
    8688void task_init(void)
    8789{
     
    9294}
    9395
    94 /*
     96/** Task finish walker.
     97 *
    9598 * The idea behind this walker is to kill and count all tasks different from
    9699 * TASK.
     100 *
    97101 */
    98102static bool task_done_walker(avltree_node_t *node, void *arg)
    99103{
    100         task_t *t = avltree_get_instance(node, task_t, tasks_tree_node);
    101         unsigned *cnt = (unsigned *) arg;
    102        
    103         if (t != TASK) {
     104        task_t *task = avltree_get_instance(node, task_t, tasks_tree_node);
     105        size_t *cnt = (size_t *) arg;
     106       
     107        if (task != TASK) {
    104108                (*cnt)++;
     109               
    105110#ifdef CONFIG_DEBUG
    106                 printf("[%"PRIu64"] ", t->taskid);
    107 #endif
    108                 task_kill_internal(t);
     111                printf("[%"PRIu64"] ", task->taskid);
     112#endif
     113               
     114                task_kill_internal(task);
    109115        }
    110116       
     
    113119}
    114120
    115 /** Kill all tasks except the current task. */
     121/** Kill all tasks except the current task.
     122 *
     123 */
    116124void task_done(void)
    117125{
    118         unsigned tasks_left;
    119        
    120         do { /* Repeat until there are any tasks except TASK */
    121                 /* Messing with task structures, avoid deadlock */
     126        size_t tasks_left;
     127       
     128        /* Repeat until there are any tasks except TASK */
     129        do {
    122130#ifdef CONFIG_DEBUG
    123131                printf("Killing tasks... ");
    124132#endif
    125                 ipl_t ipl = interrupts_disable();
    126                 spinlock_lock(&tasks_lock);
     133               
     134                irq_spinlock_lock(&tasks_lock, true);
    127135                tasks_left = 0;
    128136                avltree_walk(&tasks_tree, task_done_walker, &tasks_left);
    129                 spinlock_unlock(&tasks_lock);
    130                 interrupts_restore(ipl);
     137                irq_spinlock_unlock(&tasks_lock, true);
     138               
    131139                thread_sleep(1);
     140               
    132141#ifdef CONFIG_DEBUG
    133142                printf("\n");
    134143#endif
    135         } while (tasks_left);
    136 }
    137 
    138 int tsk_constructor(void *obj, int kmflags)
    139 {
    140         task_t *ta = obj;
    141         int i;
    142        
    143         atomic_set(&ta->refcount, 0);
    144         atomic_set(&ta->lifecount, 0);
    145         atomic_set(&ta->active_calls, 0);
    146        
    147         spinlock_initialize(&ta->lock, "task_ta_lock");
    148         mutex_initialize(&ta->futexes_lock, MUTEX_PASSIVE);
    149        
    150         list_initialize(&ta->th_head);
    151         list_initialize(&ta->sync_box_head);
    152        
    153         ipc_answerbox_init(&ta->answerbox, ta);
     144        } while (tasks_left > 0);
     145}
     146
     147int tsk_constructor(void *obj, unsigned int kmflags)
     148{
     149        task_t *task = (task_t *) obj;
     150       
     151        atomic_set(&task->refcount, 0);
     152        atomic_set(&task->lifecount, 0);
     153        atomic_set(&task->active_calls, 0);
     154       
     155        irq_spinlock_initialize(&task->lock, "task_t_lock");
     156        mutex_initialize(&task->futexes_lock, MUTEX_PASSIVE);
     157       
     158        list_initialize(&task->th_head);
     159        list_initialize(&task->sync_box_head);
     160       
     161        ipc_answerbox_init(&task->answerbox, task);
     162       
     163        size_t i;
    154164        for (i = 0; i < IPC_MAX_PHONES; i++)
    155                 ipc_phone_init(&ta->phones[i]);
     165                ipc_phone_init(&task->phones[i]);
    156166       
    157167#ifdef CONFIG_UDEBUG
    158168        /* Init kbox stuff */
    159         ta->kb.thread = NULL;
    160         ipc_answerbox_init(&ta->kb.box, ta);
    161         mutex_initialize(&ta->kb.cleanup_lock, MUTEX_PASSIVE);
     169        task->kb.thread = NULL;
     170        ipc_answerbox_init(&task->kb.box, task);
     171        mutex_initialize(&task->kb.cleanup_lock, MUTEX_PASSIVE);
    162172#endif
    163173       
     
    175185task_t *task_create(as_t *as, const char *name)
    176186{
    177         ipl_t ipl;
    178         task_t *ta;
    179        
    180         ta = (task_t *) slab_alloc(task_slab, 0);
    181         task_create_arch(ta);
    182         ta->as = as;
    183         memcpy(ta->name, name, TASK_NAME_BUFLEN);
    184         ta->name[TASK_NAME_BUFLEN - 1] = 0;
    185        
    186         ta->context = CONTEXT;
    187         ta->capabilities = 0;
    188         ta->ucycles = 0;
    189         ta->kcycles = 0;
    190 
    191         ta->ipc_info.call_sent = 0;
    192         ta->ipc_info.call_recieved = 0;
    193         ta->ipc_info.answer_sent = 0;
    194         ta->ipc_info.answer_recieved = 0;
    195         ta->ipc_info.irq_notif_recieved = 0;
    196         ta->ipc_info.forwarded = 0;
    197 
     187        task_t *task = (task_t *) slab_alloc(task_slab, 0);
     188        task_create_arch(task);
     189       
     190        task->as = as;
     191        str_cpy(task->name, TASK_NAME_BUFLEN, name);
     192       
     193        task->context = CONTEXT;
     194        task->capabilities = 0;
     195        task->ucycles = 0;
     196        task->kcycles = 0;
     197       
     198        task->ipc_info.call_sent = 0;
     199        task->ipc_info.call_recieved = 0;
     200        task->ipc_info.answer_sent = 0;
     201        task->ipc_info.answer_recieved = 0;
     202        task->ipc_info.irq_notif_recieved = 0;
     203        task->ipc_info.forwarded = 0;
     204       
    198205#ifdef CONFIG_UDEBUG
    199206        /* Init debugging stuff */
    200         udebug_task_init(&ta->udebug);
     207        udebug_task_init(&task->udebug);
    201208       
    202209        /* Init kbox stuff */
    203         ta->kb.finished = false;
     210        task->kb.finished = false;
    204211#endif
    205212       
    206213        if ((ipc_phone_0) &&
    207             (context_check(ipc_phone_0->task->context, ta->context)))
    208                 ipc_phone_connect(&ta->phones[0], ipc_phone_0);
    209        
    210         btree_create(&ta->futexes);
     214            (context_check(ipc_phone_0->task->context, task->context)))
     215                ipc_phone_connect(&task->phones[0], ipc_phone_0);
     216       
     217        btree_create(&task->futexes);
    211218       
    212219        /*
    213220         * Get a reference to the address space.
    214221         */
    215         as_hold(ta->as);
    216 
    217         ipl = interrupts_disable();
    218         spinlock_lock(&tasks_lock);
    219         ta->taskid = ++task_counter;
    220         avltree_node_initialize(&ta->tasks_tree_node);
    221         ta->tasks_tree_node.key = ta->taskid;
    222         avltree_insert(&tasks_tree, &ta->tasks_tree_node);
    223         spinlock_unlock(&tasks_lock);
    224         interrupts_restore(ipl);
    225        
    226         return ta;
     222        as_hold(task->as);
     223       
     224        irq_spinlock_lock(&tasks_lock, true);
     225       
     226        task->taskid = ++task_counter;
     227        avltree_node_initialize(&task->tasks_tree_node);
     228        task->tasks_tree_node.key = task->taskid;
     229        avltree_insert(&tasks_tree, &task->tasks_tree_node);
     230       
     231        irq_spinlock_unlock(&tasks_lock, true);
     232       
     233        return task;
    227234}
    228235
    229236/** Destroy task.
    230237 *
    231  * @param t Task to be destroyed.
    232  *
    233  */
    234 void task_destroy(task_t *t)
     238 * @param task Task to be destroyed.
     239 *
     240 */
     241void task_destroy(task_t *task)
    235242{
    236243        /*
    237244         * Remove the task from the task B+tree.
    238245         */
    239         spinlock_lock(&tasks_lock);
    240         avltree_delete(&tasks_tree, &t->tasks_tree_node);
    241         spinlock_unlock(&tasks_lock);
     246        irq_spinlock_lock(&tasks_lock, true);
     247        avltree_delete(&tasks_tree, &task->tasks_tree_node);
     248        irq_spinlock_unlock(&tasks_lock, true);
    242249       
    243250        /*
    244251         * Perform architecture specific task destruction.
    245252         */
    246         task_destroy_arch(t);
     253        task_destroy_arch(task);
    247254       
    248255        /*
    249256         * Free up dynamically allocated state.
    250257         */
    251         btree_destroy(&t->futexes);
     258        btree_destroy(&task->futexes);
    252259       
    253260        /*
    254261         * Drop our reference to the address space.
    255262         */
    256         as_release(t->as);
    257        
    258         slab_free(task_slab, t);
     263        as_release(task->as);
     264       
     265        slab_free(task_slab, task);
    259266}
    260267
     
    263270 * Holding a reference to a task prevents destruction of that task.
    264271 *
    265  * @param t             Task to be held.
    266  */
    267 void task_hold(task_t *t)
    268 {
    269         atomic_inc(&t->refcount);
     272 * @param task Task to be held.
     273 *
     274 */
     275void task_hold(task_t *task)
     276{
     277        atomic_inc(&task->refcount);
    270278}
    271279
     
    274282 * The last one to release a reference to a task destroys the task.
    275283 *
    276  * @param t             Task to be released.
    277  */
    278 void task_release(task_t *t)
    279 {
    280         if ((atomic_predec(&t->refcount)) == 0)
    281                 task_destroy(t);
     284 * @param task Task to be released.
     285 *
     286 */
     287void task_release(task_t *task)
     288{
     289        if ((atomic_predec(&task->refcount)) == 0)
     290                task_destroy(task);
    282291}
    283292
     
    346355       
    347356        if (node)
    348                 return avltree_get_instance(node, task_t, tasks_tree_node); 
     357                return avltree_get_instance(node, task_t, tasks_tree_node);
    349358       
    350359        return NULL;
     
    356365 * already disabled.
    357366 *
    358  * @param t       Pointer to thread.
     367 * @param task    Pointer to the task.
    359368 * @param ucycles Out pointer to sum of all user cycles.
    360369 * @param kcycles Out pointer to sum of all kernel cycles.
    361370 *
    362371 */
    363 void task_get_accounting(task_t *t, uint64_t *ucycles, uint64_t *kcycles)
     372void task_get_accounting(task_t *task, uint64_t *ucycles, uint64_t *kcycles)
    364373{
    365374        /* Accumulated values of task */
    366         uint64_t uret = t->ucycles;
    367         uint64_t kret = t->kcycles;
     375        uint64_t uret = task->ucycles;
     376        uint64_t kret = task->kcycles;
    368377       
    369378        /* Current values of threads */
    370379        link_t *cur;
    371         for (cur = t->th_head.next; cur != &t->th_head; cur = cur->next) {
    372                 thread_t *thr = list_get_instance(cur, thread_t, th_link);
    373                
    374                 spinlock_lock(&thr->lock);
     380        for (cur = task->th_head.next; cur != &task->th_head; cur = cur->next) {
     381                thread_t *thread = list_get_instance(cur, thread_t, th_link);
     382               
     383                irq_spinlock_lock(&thread->lock, false);
     384               
    375385                /* Process only counted threads */
    376                 if (!thr->uncounted) {
    377                         if (thr == THREAD) {
     386                if (!thread->uncounted) {
     387                        if (thread == THREAD) {
    378388                                /* Update accounting of current thread */
    379389                                thread_update_accounting(false);
    380                         }
    381                         uret += thr->ucycles;
    382                         kret += thr->kcycles;
     390                        }
     391                       
     392                        uret += thread->ucycles;
     393                        kret += thread->kcycles;
    383394                }
    384                 spinlock_unlock(&thr->lock);
     395               
     396                irq_spinlock_unlock(&thread->lock, false);
    385397        }
    386398       
     
    389401}
    390402
    391 static void task_kill_internal(task_t *ta)
     403static void task_kill_internal(task_t *task)
    392404{
    393405        link_t *cur;
     
    396408         * Interrupt all threads.
    397409         */
    398         spinlock_lock(&ta->lock);
    399         for (cur = ta->th_head.next; cur != &ta->th_head; cur = cur->next) {
    400                 thread_t *thr;
     410        irq_spinlock_lock(&task->lock, false);
     411        for (cur = task->th_head.next; cur != &task->th_head; cur = cur->next) {
     412                thread_t *thread = list_get_instance(cur, thread_t, th_link);
    401413                bool sleeping = false;
    402414               
    403                 thr = list_get_instance(cur, thread_t, th_link);
    404                
    405                 spinlock_lock(&thr->lock);
    406                 thr->interrupted = true;
    407                 if (thr->state == Sleeping)
     415                irq_spinlock_lock(&thread->lock, false);
     416               
     417                thread->interrupted = true;
     418                if (thread->state == Sleeping)
    408419                        sleeping = true;
    409                 spinlock_unlock(&thr->lock);
     420               
     421                irq_spinlock_unlock(&thread->lock, false);
    410422               
    411423                if (sleeping)
    412                         waitq_interrupt_sleep(thr);
     424                        waitq_interrupt_sleep(thread);
    413425        }
    414         spinlock_unlock(&ta->lock);
     426       
     427        irq_spinlock_unlock(&task->lock, false);
    415428}
    416429
     
    427440int task_kill(task_id_t id)
    428441{
    429         ipl_t ipl;
    430         task_t *ta;
    431 
    432442        if (id == 1)
    433443                return EPERM;
    434444       
    435         ipl = interrupts_disable();
    436         spinlock_lock(&tasks_lock);
    437         if (!(ta = task_find_by_id(id))) {
    438                 spinlock_unlock(&tasks_lock);
    439                 interrupts_restore(ipl);
     445        irq_spinlock_lock(&tasks_lock, true);
     446       
     447        task_t *task = task_find_by_id(id);
     448        if (!task) {
     449                irq_spinlock_unlock(&tasks_lock, true);
    440450                return ENOENT;
    441451        }
    442         task_kill_internal(ta);
    443         spinlock_unlock(&tasks_lock);
    444         interrupts_restore(ipl);
    445         return 0;
     452       
     453        task_kill_internal(task);
     454        irq_spinlock_unlock(&tasks_lock, true);
     455       
     456        return EOK;
    446457}
    447458
    448459static bool task_print_walker(avltree_node_t *node, void *arg)
    449460{
    450         task_t *t = avltree_get_instance(node, task_t, tasks_tree_node);
    451         int j;
    452        
    453         spinlock_lock(&t->lock);
     461        task_t *task = avltree_get_instance(node, task_t, tasks_tree_node);
     462        irq_spinlock_lock(&task->lock, false);
    454463       
    455464        uint64_t ucycles;
    456465        uint64_t kcycles;
    457466        char usuffix, ksuffix;
    458         task_get_accounting(t, &ucycles, &kcycles);
     467        task_get_accounting(task, &ucycles, &kcycles);
    459468        order_suffix(ucycles, &ucycles, &usuffix);
    460469        order_suffix(kcycles, &kcycles, &ksuffix);
    461470       
    462 #ifdef __32_BITS__     
     471#ifdef __32_BITS__
    463472        printf("%-6" PRIu64 " %-12s %-3" PRIu32 " %10p %10p %9" PRIu64 "%c %9"
    464                 PRIu64 "%c %7ld %6ld", t->taskid, t->name, t->context, t, t->as,
    465                 ucycles, usuffix, kcycles, ksuffix, atomic_get(&t->refcount),
    466                 atomic_get(&t->active_calls));
     473            PRIu64 "%c %7ld %6ld", task->taskid, task->name, task->context,
     474            task, task->as, ucycles, usuffix, kcycles, ksuffix,
     475            atomic_get(&task->refcount), atomic_get(&task->active_calls));
    467476#endif
    468477       
    469478#ifdef __64_BITS__
    470479        printf("%-6" PRIu64 " %-12s %-3" PRIu32 " %18p %18p %9" PRIu64 "%c %9"
    471                 PRIu64 "%c %7ld %6ld", t->taskid, t->name, t->context, t, t->as,
    472                 ucycles, usuffix, kcycles, ksuffix, atomic_get(&t->refcount),
    473                 atomic_get(&t->active_calls));
    474 #endif
    475        
    476         for (j = 0; j < IPC_MAX_PHONES; j++) {
    477                 if (t->phones[j].callee)
    478                         printf(" %d:%p", j, t->phones[j].callee);
     480            PRIu64 "%c %7ld %6ld", task->taskid, task->name, task->context,
     481            task, task->as, ucycles, usuffix, kcycles, ksuffix,
     482            atomic_get(&task->refcount), atomic_get(&task->active_calls));
     483#endif
     484       
     485        size_t i;
     486        for (i = 0; i < IPC_MAX_PHONES; i++) {
     487                if (task->phones[i].callee)
     488                        printf(" %" PRIs ":%p", i, task->phones[i].callee);
    479489        }
    480490        printf("\n");
    481491       
    482         spinlock_unlock(&t->lock);
     492        irq_spinlock_unlock(&task->lock, false);
    483493        return true;
    484494}
     
    487497void task_print_list(void)
    488498{
    489         ipl_t ipl;
    490        
    491499        /* Messing with task structures, avoid deadlock */
    492         ipl = interrupts_disable();
    493         spinlock_lock(&tasks_lock);
     500        irq_spinlock_lock(&tasks_lock, true);
    494501       
    495502#ifdef __32_BITS__
     
    509516        avltree_walk(&tasks_tree, task_print_walker, NULL);
    510517       
    511         spinlock_unlock(&tasks_lock);
    512         interrupts_restore(ipl);
     518        irq_spinlock_unlock(&tasks_lock, true);
    513519}
    514520
  • kernel/generic/src/proc/thread.c

    r666f492 rda1bafb  
    3333/**
    3434 * @file
    35  * @brief       Thread management functions.
     35 * @brief Thread management functions.
    3636 */
    3737
     
    9494 *
    9595 * For locking rules, see declaration thereof.
    96  */
    97 SPINLOCK_INITIALIZE(threads_lock);
     96 *
     97 */
     98IRQ_SPINLOCK_INITIALIZE(threads_lock);
    9899
    99100/** AVL tree of all threads.
     
    101102 * When a thread is found in the threads_tree AVL tree, it is guaranteed to
    102103 * exist as long as the threads_lock is held.
    103  */
    104 avltree_t threads_tree;         
    105 
    106 SPINLOCK_INITIALIZE(tidlock);
    107 thread_id_t last_tid = 0;
     104 *
     105 */
     106avltree_t threads_tree;
     107
     108IRQ_SPINLOCK_STATIC_INITIALIZE(tidlock);
     109static thread_id_t last_tid = 0;
    108110
    109111static slab_cache_t *thread_slab;
     112
    110113#ifdef CONFIG_FPU
    111114slab_cache_t *fpu_context_slab;
     
    125128        void *arg = THREAD->thread_arg;
    126129        THREAD->last_cycle = get_cycle();
    127 
     130       
    128131        /* This is where each thread wakes up after its creation */
    129         spinlock_unlock(&THREAD->lock);
     132        irq_spinlock_unlock(&THREAD->lock, false);
    130133        interrupts_enable();
    131 
     134       
    132135        f(arg);
    133136       
    134137        /* Accumulate accounting to the task */
    135         ipl_t ipl = interrupts_disable();
    136        
    137         spinlock_lock(&THREAD->lock);
     138        irq_spinlock_lock(&THREAD->lock, true);
    138139        if (!THREAD->uncounted) {
    139140                thread_update_accounting(true);
     
    142143                uint64_t kcycles = THREAD->kcycles;
    143144                THREAD->kcycles = 0;
    144 
    145                 spinlock_unlock(&THREAD->lock);
    146145               
    147                 spinlock_lock(&TASK->lock);
     146                irq_spinlock_pass(&THREAD->lock, &TASK->lock);
    148147                TASK->ucycles += ucycles;
    149148                TASK->kcycles += kcycles;
    150                 spinlock_unlock(&TASK->lock);
     149                irq_spinlock_unlock(&TASK->lock, true);
    151150        } else
    152                 spinlock_unlock(&THREAD->lock);
    153        
    154         interrupts_restore(ipl);
     151                irq_spinlock_unlock(&THREAD->lock, true);
    155152       
    156153        thread_exit();
    157         /* not reached */
    158 }
    159 
    160 /** Initialization and allocation for thread_t structure */
    161 static int thr_constructor(void *obj, int kmflags)
    162 {
    163         thread_t *t = (thread_t *) obj;
    164 
    165         spinlock_initialize(&t->lock, "thread_t_lock");
    166         link_initialize(&t->rq_link);
    167         link_initialize(&t->wq_link);
    168         link_initialize(&t->th_link);
    169 
     154       
     155        /* Not reached */
     156}
     157
     158/** Initialization and allocation for thread_t structure
     159 *
     160 */
     161static int thr_constructor(void *obj, unsigned int kmflags)
     162{
     163        thread_t *thread = (thread_t *) obj;
     164       
     165        irq_spinlock_initialize(&thread->lock, "thread_t_lock");
     166        link_initialize(&thread->rq_link);
     167        link_initialize(&thread->wq_link);
     168        link_initialize(&thread->th_link);
     169       
    170170        /* call the architecture-specific part of the constructor */
    171         thr_constructor_arch(t);
     171        thr_constructor_arch(thread);
    172172       
    173173#ifdef CONFIG_FPU
    174174#ifdef CONFIG_FPU_LAZY
    175         t->saved_fpu_context = NULL;
    176 #else
    177         t->saved_fpu_context = slab_alloc(fpu_context_slab, kmflags);
    178         if (!t->saved_fpu_context)
     175        thread->saved_fpu_context = NULL;
     176#else /* CONFIG_FPU_LAZY */
     177        thread->saved_fpu_context = slab_alloc(fpu_context_slab, kmflags);
     178        if (!thread->saved_fpu_context)
    179179                return -1;
    180 #endif
    181 #endif
    182 
    183         t->kstack = (uint8_t *) frame_alloc(STACK_FRAMES, FRAME_KA | kmflags);
    184         if (!t->kstack) {
     180#endif /* CONFIG_FPU_LAZY */
     181#endif /* CONFIG_FPU */
     182       
     183        thread->kstack = (uint8_t *) frame_alloc(STACK_FRAMES, FRAME_KA | kmflags);
     184        if (!thread->kstack) {
    185185#ifdef CONFIG_FPU
    186                 if (t->saved_fpu_context)
    187                         slab_free(fpu_context_slab, t->saved_fpu_context);
     186                if (thread->saved_fpu_context)
     187                        slab_free(fpu_context_slab, thread->saved_fpu_context);
    188188#endif
    189189                return -1;
    190190        }
    191 
     191       
    192192#ifdef CONFIG_UDEBUG
    193         mutex_initialize(&t->udebug.lock, MUTEX_PASSIVE);
    194 #endif
    195 
     193        mutex_initialize(&thread->udebug.lock, MUTEX_PASSIVE);
     194#endif
     195       
    196196        return 0;
    197197}
    198198
    199199/** Destruction of thread_t object */
    200 static int thr_destructor(void *obj)
    201 {
    202         thread_t *t = (thread_t *) obj;
    203 
     200static size_t thr_destructor(void *obj)
     201{
     202        thread_t *thread = (thread_t *) obj;
     203       
    204204        /* call the architecture-specific part of the destructor */
    205         thr_destructor_arch(t);
    206 
    207         frame_free(KA2PA(t->kstack));
     205        thr_destructor_arch(thread);
     206       
     207        frame_free(KA2PA(thread->kstack));
     208       
    208209#ifdef CONFIG_FPU
    209         if (t->saved_fpu_context)
    210                 slab_free(fpu_context_slab, t->saved_fpu_context);
    211 #endif
    212         return 1; /* One page freed */
     210        if (thread->saved_fpu_context)
     211                slab_free(fpu_context_slab, thread->saved_fpu_context);
     212#endif
     213       
     214        return 1;  /* One page freed */
    213215}
    214216
     
    221223{
    222224        THREAD = NULL;
     225       
    223226        atomic_set(&nrdy, 0);
    224227        thread_slab = slab_cache_create("thread_slab", sizeof(thread_t), 0,
    225228            thr_constructor, thr_destructor, 0);
    226 
     229       
    227230#ifdef CONFIG_FPU
    228231        fpu_context_slab = slab_cache_create("fpu_slab", sizeof(fpu_context_t),
    229232            FPU_CONTEXT_ALIGN, NULL, NULL, 0);
    230233#endif
    231 
     234       
    232235        avltree_create(&threads_tree);
    233236}
     
    235238/** Make thread ready
    236239 *
    237  * Switch thread t to the ready state.
     240 * Switch thread to the ready state.
    238241 *
    239242 * @param t Thread to make ready.
    240243 *
    241244 */
    242 void thread_ready(thread_t *t)
    243 {
    244         cpu_t *cpu;
    245         runq_t *r;
    246         ipl_t ipl;
    247         int i, avg;
    248 
    249         ipl = interrupts_disable();
    250 
    251         spinlock_lock(&t->lock);
    252 
    253         ASSERT(!(t->state == Ready));
    254 
    255         i = (t->priority < RQ_COUNT - 1) ? ++t->priority : t->priority;
    256        
    257         cpu = CPU;
    258         if (t->flags & THREAD_FLAG_WIRED) {
    259                 ASSERT(t->cpu != NULL);
    260                 cpu = t->cpu;
     245void thread_ready(thread_t *thread)
     246{
     247        irq_spinlock_lock(&thread->lock, true);
     248       
     249        ASSERT(!(thread->state == Ready));
     250       
     251        int i = (thread->priority < RQ_COUNT - 1)
     252            ? ++thread->priority : thread->priority;
     253       
     254        cpu_t *cpu = CPU;
     255        if (thread->flags & THREAD_FLAG_WIRED) {
     256                ASSERT(thread->cpu != NULL);
     257                cpu = thread->cpu;
    261258        }
    262         t->state = Ready;
    263         spinlock_unlock(&t->lock);
     259        thread->state = Ready;
     260       
     261        irq_spinlock_pass(&thread->lock, &(cpu->rq[i].lock));
    264262       
    265263        /*
    266          * Append t to respective ready queue on respective processor.
     264         * Append thread to respective ready queue
     265         * on respective processor.
    267266         */
    268         r = &cpu->rq[i];
    269         spinlock_lock(&r->lock);
    270         list_append(&t->rq_link, &r->rq_head);
    271         r->n++;
    272         spinlock_unlock(&r->lock);
    273 
     267       
     268        list_append(&thread->rq_link, &cpu->rq[i].rq_head);
     269        cpu->rq[i].n++;
     270        irq_spinlock_unlock(&(cpu->rq[i].lock), true);
     271       
    274272        atomic_inc(&nrdy);
    275         // FIXME: Why is the avg value never read?
    276         avg = atomic_get(&nrdy) / config.cpu_active;
     273        // FIXME: Why is the avg value not used
     274        // avg = atomic_get(&nrdy) / config.cpu_active;
    277275        atomic_inc(&cpu->nrdy);
    278 
     276}
     277
     278/** Create new thread
     279 *
     280 * Create a new thread.
     281 *
     282 * @param func      Thread's implementing function.
     283 * @param arg       Thread's implementing function argument.
     284 * @param task      Task to which the thread belongs. The caller must
     285 *                  guarantee that the task won't cease to exist during the
     286 *                  call. The task's lock may not be held.
     287 * @param flags     Thread flags.
     288 * @param name      Symbolic name (a copy is made).
     289 * @param uncounted Thread's accounting doesn't affect accumulated task
     290 *                  accounting.
     291 *
     292 * @return New thread's structure on success, NULL on failure.
     293 *
     294 */
     295thread_t *thread_create(void (* func)(void *), void *arg, task_t *task,
     296    unsigned int flags, const char *name, bool uncounted)
     297{
     298        thread_t *thread = (thread_t *) slab_alloc(thread_slab, 0);
     299        if (!thread)
     300                return NULL;
     301       
     302        /* Not needed, but good for debugging */
     303        memsetb(thread->kstack, THREAD_STACK_SIZE * 1 << STACK_FRAMES, 0);
     304       
     305        irq_spinlock_lock(&tidlock, true);
     306        thread->tid = ++last_tid;
     307        irq_spinlock_unlock(&tidlock, true);
     308       
     309        context_save(&thread->saved_context);
     310        context_set(&thread->saved_context, FADDR(cushion),
     311            (uintptr_t) thread->kstack, THREAD_STACK_SIZE);
     312       
     313        the_initialize((the_t *) thread->kstack);
     314       
     315        ipl_t ipl = interrupts_disable();
     316        thread->saved_context.ipl = interrupts_read();
    279317        interrupts_restore(ipl);
    280 }
    281 
    282 /** Create new thread
    283  *
    284  * Create a new thread.
    285  *
    286  * @param func          Thread's implementing function.
    287  * @param arg           Thread's implementing function argument.
    288  * @param task          Task to which the thread belongs. The caller must
    289  *                      guarantee that the task won't cease to exist during the
    290  *                      call. The task's lock may not be held.
    291  * @param flags         Thread flags.
    292  * @param name          Symbolic name (a copy is made).
    293  * @param uncounted     Thread's accounting doesn't affect accumulated task
    294  *                      accounting.
    295  *
    296  * @return              New thread's structure on success, NULL on failure.
    297  *
    298  */
    299 thread_t *thread_create(void (* func)(void *), void *arg, task_t *task,
    300     int flags, const char *name, bool uncounted)
    301 {
    302         thread_t *t;
    303         ipl_t ipl;
    304        
    305         t = (thread_t *) slab_alloc(thread_slab, 0);
    306         if (!t)
    307                 return NULL;
    308        
    309         /* Not needed, but good for debugging */
    310         memsetb(t->kstack, THREAD_STACK_SIZE * 1 << STACK_FRAMES, 0);
    311        
    312         ipl = interrupts_disable();
    313         spinlock_lock(&tidlock);
    314         t->tid = ++last_tid;
    315         spinlock_unlock(&tidlock);
    316         interrupts_restore(ipl);
    317        
    318         context_save(&t->saved_context);
    319         context_set(&t->saved_context, FADDR(cushion), (uintptr_t) t->kstack,
    320             THREAD_STACK_SIZE);
    321        
    322         the_initialize((the_t *) t->kstack);
    323        
    324         ipl = interrupts_disable();
    325         t->saved_context.ipl = interrupts_read();
    326         interrupts_restore(ipl);
    327        
    328         memcpy(t->name, name, THREAD_NAME_BUFLEN);
    329         t->name[THREAD_NAME_BUFLEN - 1] = 0;
    330        
    331         t->thread_code = func;
    332         t->thread_arg = arg;
    333         t->ticks = -1;
    334         t->ucycles = 0;
    335         t->kcycles = 0;
    336         t->uncounted = uncounted;
    337         t->priority = -1;               /* start in rq[0] */
    338         t->cpu = NULL;
    339         t->flags = flags;
    340         t->state = Entering;
    341         t->call_me = NULL;
    342         t->call_me_with = NULL;
    343        
    344         timeout_initialize(&t->sleep_timeout);
    345         t->sleep_interruptible = false;
    346         t->sleep_queue = NULL;
    347         t->timeout_pending = 0;
    348 
    349         t->in_copy_from_uspace = false;
    350         t->in_copy_to_uspace = false;
    351 
    352         t->interrupted = false;
    353         t->detached = false;
    354         waitq_initialize(&t->join_wq);
    355        
    356         t->rwlock_holder_type = RWLOCK_NONE;
    357                
    358         t->task = task;
    359        
    360         t->fpu_context_exists = 0;
    361         t->fpu_context_engaged = 0;
    362 
    363         avltree_node_initialize(&t->threads_tree_node);
    364         t->threads_tree_node.key = (uintptr_t) t;
    365 
     318       
     319        str_cpy(thread->name, THREAD_NAME_BUFLEN, name);
     320       
     321        thread->thread_code = func;
     322        thread->thread_arg = arg;
     323        thread->ticks = -1;
     324        thread->ucycles = 0;
     325        thread->kcycles = 0;
     326        thread->uncounted = uncounted;
     327        thread->priority = -1;          /* Start in rq[0] */
     328        thread->cpu = NULL;
     329        thread->flags = flags;
     330        thread->state = Entering;
     331        thread->call_me = NULL;
     332        thread->call_me_with = NULL;
     333       
     334        timeout_initialize(&thread->sleep_timeout);
     335        thread->sleep_interruptible = false;
     336        thread->sleep_queue = NULL;
     337        thread->timeout_pending = false;
     338       
     339        thread->in_copy_from_uspace = false;
     340        thread->in_copy_to_uspace = false;
     341       
     342        thread->interrupted = false;
     343        thread->detached = false;
     344        waitq_initialize(&thread->join_wq);
     345       
     346        thread->rwlock_holder_type = RWLOCK_NONE;
     347       
     348        thread->task = task;
     349       
     350        thread->fpu_context_exists = 0;
     351        thread->fpu_context_engaged = 0;
     352       
     353        avltree_node_initialize(&thread->threads_tree_node);
     354        thread->threads_tree_node.key = (uintptr_t) thread;
     355       
    366356#ifdef CONFIG_UDEBUG
    367357        /* Init debugging stuff */
    368         udebug_thread_initialize(&t->udebug);
    369 #endif
    370 
    371         /* might depend on previous initialization */
    372         thread_create_arch(t); 
    373 
     358        udebug_thread_initialize(&thread->udebug);
     359#endif
     360       
     361        /* Might depend on previous initialization */
     362        thread_create_arch(thread);
     363       
    374364        if (!(flags & THREAD_FLAG_NOATTACH))
    375                 thread_attach(t, task);
    376 
    377         return t;
     365                thread_attach(thread, task);
     366       
     367        return thread;
    378368}
    379369
     
    381371 *
    382372 * Detach thread from all queues, cpus etc. and destroy it.
    383  *
    384  * Assume thread->lock is held!!
    385  */
    386 void thread_destroy(thread_t *t)
    387 {
    388         ASSERT(t->state == Exiting || t->state == Lingering);
    389         ASSERT(t->task);
    390         ASSERT(t->cpu);
    391 
    392         spinlock_lock(&t->cpu->lock);
    393         if (t->cpu->fpu_owner == t)
    394                 t->cpu->fpu_owner = NULL;
    395         spinlock_unlock(&t->cpu->lock);
    396 
    397         spinlock_unlock(&t->lock);
    398 
    399         spinlock_lock(&threads_lock);
    400         avltree_delete(&threads_tree, &t->threads_tree_node);
    401         spinlock_unlock(&threads_lock);
    402 
     373 * Assume thread->lock is held!
     374 *
     375 * @param thread  Thread to be destroyed.
     376 * @param irq_res Indicate whether it should unlock thread->lock
     377 *                in interrupts-restore mode.
     378 *
     379 */
     380void thread_destroy(thread_t *thread, bool irq_res)
     381{
     382        ASSERT((thread->state == Exiting) || (thread->state == Lingering));
     383        ASSERT(thread->task);
     384        ASSERT(thread->cpu);
     385       
     386        irq_spinlock_lock(&thread->cpu->lock, false);
     387        if (thread->cpu->fpu_owner == thread)
     388                thread->cpu->fpu_owner = NULL;
     389        irq_spinlock_unlock(&thread->cpu->lock, false);
     390       
     391        irq_spinlock_pass(&thread->lock, &threads_lock);
     392       
     393        avltree_delete(&threads_tree, &thread->threads_tree_node);
     394       
     395        irq_spinlock_pass(&threads_lock, &thread->task->lock);
     396       
    403397        /*
    404398         * Detach from the containing task.
    405399         */
    406         spinlock_lock(&t->task->lock);
    407         list_remove(&t->th_link);
    408         spinlock_unlock(&t->task->lock);       
    409 
     400        list_remove(&thread->th_link);
     401        irq_spinlock_unlock(&thread->task->lock, irq_res);
     402       
    410403        /*
    411404         * Drop the reference to the containing task.
    412405         */
    413         task_release(t->task);
    414        
    415         slab_free(thread_slab, t);
     406        task_release(thread->task);
     407        slab_free(thread_slab, thread);
    416408}
    417409
     
    421413 * threads_tree.
    422414 *
    423  * @param t     Thread to be attached to the task.
    424  * @param task  Task to which the thread is to be attached.
    425  */
    426 void thread_attach(thread_t *t, task_t *task)
    427 {
    428         ipl_t ipl;
    429 
     415 * @param t    Thread to be attached to the task.
     416 * @param task Task to which the thread is to be attached.
     417 *
     418 */
     419void thread_attach(thread_t *thread, task_t *task)
     420{
    430421        /*
    431422         * Attach to the specified task.
    432423         */
    433         ipl = interrupts_disable();
    434         spinlock_lock(&task->lock);
    435 
     424        irq_spinlock_lock(&task->lock, true);
     425       
    436426        /* Hold a reference to the task. */
    437427        task_hold(task);
    438 
     428       
    439429        /* Must not count kbox thread into lifecount */
    440         if (t->flags & THREAD_FLAG_USPACE)
     430        if (thread->flags & THREAD_FLAG_USPACE)
    441431                atomic_inc(&task->lifecount);
    442 
    443         list_append(&t->th_link, &task->th_head);
    444         spinlock_unlock(&task->lock);
    445 
     432       
     433        list_append(&thread->th_link, &task->th_head);
     434       
     435        irq_spinlock_pass(&task->lock, &threads_lock);
     436       
    446437        /*
    447438         * Register this thread in the system-wide list.
    448439         */
    449         spinlock_lock(&threads_lock);
    450         avltree_insert(&threads_tree, &t->threads_tree_node);
    451         spinlock_unlock(&threads_lock);
    452        
    453         interrupts_restore(ipl);
     440        avltree_insert(&threads_tree, &thread->threads_tree_node);
     441        irq_spinlock_unlock(&threads_lock, true);
    454442}
    455443
    456444/** Terminate thread.
    457445 *
    458  * End current thread execution and switch it to the exiting state. All pending
    459  * timeouts are executed.
     446 * End current thread execution and switch it to the exiting state.
     447 * All pending timeouts are executed.
     448 *
    460449 */
    461450void thread_exit(void)
    462451{
    463         ipl_t ipl;
    464 
    465452        if (THREAD->flags & THREAD_FLAG_USPACE) {
    466453#ifdef CONFIG_UDEBUG
     
    475462                         * can only be created by threads of the same task.
    476463                         * We are safe to perform cleanup.
     464                         *
    477465                         */
    478466                        ipc_cleanup();
     
    481469                }
    482470        }
    483 
     471       
    484472restart:
    485         ipl = interrupts_disable();
    486         spinlock_lock(&THREAD->lock);
    487         if (THREAD->timeout_pending) {
    488                 /* busy waiting for timeouts in progress */
    489                 spinlock_unlock(&THREAD->lock);
    490                 interrupts_restore(ipl);
     473        irq_spinlock_lock(&THREAD->lock, true);
     474        if (THREAD->timeout_pending) {
     475                /* Busy waiting for timeouts in progress */
     476                irq_spinlock_unlock(&THREAD->lock, true);
    491477                goto restart;
    492478        }
    493479       
    494480        THREAD->state = Exiting;
    495         spinlock_unlock(&THREAD->lock);
     481        irq_spinlock_unlock(&THREAD->lock, true);
     482       
    496483        scheduler();
    497 
     484       
    498485        /* Not reached */
    499         while (1)
    500                 ;
    501 }
    502 
     486        while (true);
     487}
    503488
    504489/** Thread sleep
     
    515500        while (sec > 0) {
    516501                uint32_t period = (sec > 1000) ? 1000 : sec;
    517        
     502               
    518503                thread_usleep(period * 1000000);
    519504                sec -= period;
     
    523508/** Wait for another thread to exit.
    524509 *
    525  * @param t Thread to join on exit.
    526  * @param usec Timeout in microseconds.
    527  * @param flags Mode of operation.
     510 * @param thread Thread to join on exit.
     511 * @param usec   Timeout in microseconds.
     512 * @param flags  Mode of operation.
    528513 *
    529514 * @return An error code from errno.h or an error code from synch.h.
    530  */
    531 int thread_join_timeout(thread_t *t, uint32_t usec, int flags)
    532 {
    533         ipl_t ipl;
    534         int rc;
    535 
    536         if (t == THREAD)
     515 *
     516 */
     517int thread_join_timeout(thread_t *thread, uint32_t usec, unsigned int flags)
     518{
     519        if (thread == THREAD)
    537520                return EINVAL;
    538 
     521       
    539522        /*
    540523         * Since thread join can only be called once on an undetached thread,
     
    542525         */
    543526       
    544         ipl = interrupts_disable();
    545         spinlock_lock(&t->lock);
    546         ASSERT(!t->detached);
    547         spinlock_unlock(&t->lock);
    548         interrupts_restore(ipl);
    549        
    550         rc = waitq_sleep_timeout(&t->join_wq, usec, flags);
    551        
    552         return rc;     
     527        irq_spinlock_lock(&thread->lock, true);
     528        ASSERT(!thread->detached);
     529        irq_spinlock_unlock(&thread->lock, true);
     530       
     531        return waitq_sleep_timeout(&thread->join_wq, usec, flags);
    553532}
    554533
     
    558537 * state, deallocate its resources.
    559538 *
    560  * @param t Thread to be detached.
    561  */
    562 void thread_detach(thread_t *t)
    563 {
    564         ipl_t ipl;
    565 
     539 * @param thread Thread to be detached.
     540 *
     541 */
     542void thread_detach(thread_t *thread)
     543{
    566544        /*
    567545         * Since the thread is expected not to be already detached,
    568546         * pointer to it must be still valid.
    569547         */
    570         ipl = interrupts_disable();
    571         spinlock_lock(&t->lock);
    572         ASSERT(!t->detached);
    573         if (t->state == Lingering) {
    574                 thread_destroy(t);      /* unlocks &t->lock */
    575                 interrupts_restore(ipl);
     548        irq_spinlock_lock(&thread->lock, true);
     549        ASSERT(!thread->detached);
     550       
     551        if (thread->state == Lingering) {
     552                /*
     553                 * Unlock &thread->lock and restore
     554                 * interrupts in thread_destroy().
     555                 */
     556                thread_destroy(thread, true);
    576557                return;
    577558        } else {
    578                 t->detached = true;
     559                thread->detached = true;
    579560        }
    580         spinlock_unlock(&t->lock);
    581         interrupts_restore(ipl);
     561       
     562        irq_spinlock_unlock(&thread->lock, true);
    582563}
    583564
     
    601582 *
    602583 * Register a function and its argument to be executed
    603  * on next context switch to the current thread.
     584 * on next context switch to the current thread. Must
     585 * be called with interrupts disabled.
    604586 *
    605587 * @param call_me      Out-of-context function.
     
    609591void thread_register_call_me(void (* call_me)(void *), void *call_me_with)
    610592{
    611         ipl_t ipl;
    612        
    613         ipl = interrupts_disable();
    614         spinlock_lock(&THREAD->lock);
     593        irq_spinlock_lock(&THREAD->lock, false);
    615594        THREAD->call_me = call_me;
    616595        THREAD->call_me_with = call_me_with;
    617         spinlock_unlock(&THREAD->lock);
    618         interrupts_restore(ipl);
     596        irq_spinlock_unlock(&THREAD->lock, false);
    619597}
    620598
    621599static bool thread_walker(avltree_node_t *node, void *arg)
    622600{
    623         thread_t *t = avltree_get_instance(node, thread_t, threads_tree_node);
     601        thread_t *thread = avltree_get_instance(node, thread_t, threads_tree_node);
    624602       
    625603        uint64_t ucycles, kcycles;
    626604        char usuffix, ksuffix;
    627         order_suffix(t->ucycles, &ucycles, &usuffix);
    628         order_suffix(t->kcycles, &kcycles, &ksuffix);
    629 
     605        order_suffix(thread->ucycles, &ucycles, &usuffix);
     606        order_suffix(thread->kcycles, &kcycles, &ksuffix);
     607       
    630608#ifdef __32_BITS__
    631609        printf("%-6" PRIu64" %-10s %10p %-8s %10p %-3" PRIu32 " %10p %10p %9"
    632                 PRIu64 "%c %9" PRIu64 "%c ", t->tid, t->name, t,
    633                 thread_states[t->state], t->task, t->task->context, t->thread_code,
    634                 t->kstack, ucycles, usuffix, kcycles, ksuffix);
    635 #endif
    636 
     610                PRIu64 "%c %9" PRIu64 "%c ", thread->tid, thread->name, thread,
     611                thread_states[thread->state], thread->task, thread->task->context,
     612                thread->thread_code, thread->kstack, ucycles, usuffix, kcycles, ksuffix);
     613#endif
     614       
    637615#ifdef __64_BITS__
    638616        printf("%-6" PRIu64" %-10s %18p %-8s %18p %-3" PRIu32 " %18p %18p %9"
    639                 PRIu64 "%c %9" PRIu64 "%c ", t->tid, t->name, t,
    640                 thread_states[t->state], t->task, t->task->context, t->thread_code,
    641                 t->kstack, ucycles, usuffix, kcycles, ksuffix);
    642 #endif
    643                        
    644         if (t->cpu)
    645                 printf("%-4u", t->cpu->id);
     617                PRIu64 "%c %9" PRIu64 "%c ", thread->tid, thread->name, thread,
     618                thread_states[thread->state], thread->task, thread->task->context,
     619                thread->thread_code, thread->kstack, ucycles, usuffix, kcycles, ksuffix);
     620#endif
     621       
     622        if (thread->cpu)
     623                printf("%-4u", thread->cpu->id);
    646624        else
    647625                printf("none");
    648                        
    649         if (t->state == Sleeping) {
     626       
     627        if (thread->state == Sleeping) {
    650628#ifdef __32_BITS__
    651                 printf(" %10p", t->sleep_queue);
    652 #endif
    653 
     629                printf(" %10p", thread->sleep_queue);
     630#endif
     631               
    654632#ifdef __64_BITS__
    655                 printf(" %18p", t->sleep_queue);
     633                printf(" %18p", thread->sleep_queue);
    656634#endif
    657635        }
    658                        
     636       
    659637        printf("\n");
    660 
     638       
    661639        return true;
    662640}
    663641
    664 /** Print list of threads debug info */
     642/** Print list of threads debug info
     643 *
     644 */
    665645void thread_print_list(void)
    666646{
    667         ipl_t ipl;
    668        
    669647        /* Messing with thread structures, avoid deadlock */
    670         ipl = interrupts_disable();
    671         spinlock_lock(&threads_lock);
    672 
    673 #ifdef __32_BITS__     
     648        irq_spinlock_lock(&threads_lock, true);
     649       
     650#ifdef __32_BITS__
    674651        printf("tid    name       address    state    task       "
    675652                "ctx code       stack      ucycles    kcycles    cpu  "
     
    679656                "----------\n");
    680657#endif
    681 
     658       
    682659#ifdef __64_BITS__
    683660        printf("tid    name       address            state    task               "
     
    688665                "------------------\n");
    689666#endif
    690 
     667       
    691668        avltree_walk(&threads_tree, thread_walker, NULL);
    692 
    693         spinlock_unlock(&threads_lock);
    694         interrupts_restore(ipl);
     669       
     670        irq_spinlock_unlock(&threads_lock, true);
    695671}
    696672
     
    700676 * interrupts must be already disabled.
    701677 *
    702  * @param t Pointer to thread.
     678 * @param thread Pointer to thread.
    703679 *
    704680 * @return True if thread t is known to the system, false otherwise.
    705  */
    706 bool thread_exists(thread_t *t)
    707 {
    708         avltree_node_t *node;
    709 
    710         node = avltree_search(&threads_tree, (avltree_key_t) ((uintptr_t) t));
     681 *
     682 */
     683bool thread_exists(thread_t *thread)
     684{
     685        avltree_node_t *node =
     686            avltree_search(&threads_tree, (avltree_key_t) ((uintptr_t) thread));
    711687       
    712688        return node != NULL;
     
    718694 * interrupts must be already disabled.
    719695 *
    720  * @param user  True to update user accounting, false for kernel.
     696 * @param user True to update user accounting, false for kernel.
     697 *
    721698 */
    722699void thread_update_accounting(bool user)
    723700{
    724701        uint64_t time = get_cycle();
    725         if (user) {
     702       
     703        if (user)
    726704                THREAD->ucycles += time - THREAD->last_cycle;
    727         } else {
     705        else
    728706                THREAD->kcycles += time - THREAD->last_cycle;
    729         }
     707       
    730708        THREAD->last_cycle = time;
    731709}
     
    774752    size_t name_len, thread_id_t *uspace_thread_id)
    775753{
    776         thread_t *t;
    777         char namebuf[THREAD_NAME_BUFLEN];
    778         uspace_arg_t *kernel_uarg;
    779         int rc;
    780 
    781754        if (name_len > THREAD_NAME_BUFLEN - 1)
    782755                name_len = THREAD_NAME_BUFLEN - 1;
    783 
    784         rc = copy_from_uspace(namebuf, uspace_name, name_len);
     756       
     757        char namebuf[THREAD_NAME_BUFLEN];
     758        int rc = copy_from_uspace(namebuf, uspace_name, name_len);
    785759        if (rc != 0)
    786760                return (unative_t) rc;
    787 
     761       
    788762        namebuf[name_len] = 0;
    789 
     763       
    790764        /*
    791765         * In case of failure, kernel_uarg will be deallocated in this function.
    792766         * In case of success, kernel_uarg will be freed in uinit().
     767         *
    793768         */
    794         kernel_uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t), 0);
     769        uspace_arg_t *kernel_uarg =
     770            (uspace_arg_t *) malloc(sizeof(uspace_arg_t), 0);
    795771       
    796772        rc = copy_from_uspace(kernel_uarg, uspace_uarg, sizeof(uspace_arg_t));
     
    799775                return (unative_t) rc;
    800776        }
    801 
    802         t = thread_create(uinit, kernel_uarg, TASK,
     777       
     778        thread_t *thread = thread_create(uinit, kernel_uarg, TASK,
    803779            THREAD_FLAG_USPACE | THREAD_FLAG_NOATTACH, namebuf, false);
    804         if (t) {
     780        if (thread) {
    805781                if (uspace_thread_id != NULL) {
    806                         int rc;
    807 
    808                         rc = copy_to_uspace(uspace_thread_id, &t->tid,
    809                             sizeof(t->tid));
     782                        rc = copy_to_uspace(uspace_thread_id, &thread->tid,
     783                            sizeof(thread->tid));
    810784                        if (rc != 0) {
    811785                                /*
     
    813787                                 * has already been created. We need to undo its
    814788                                 * creation now.
     789                                 *
    815790                                 */
    816 
     791                               
    817792                                /*
    818793                                 * The new thread structure is initialized, but
     
    820795                                 * We can safely deallocate it.
    821796                                 */
    822                                 slab_free(thread_slab, t);
    823                                 free(kernel_uarg);
    824 
     797                                slab_free(thread_slab, thread);
     798                                free(kernel_uarg);
     799                               
    825800                                return (unative_t) rc;
    826801                         }
    827802                }
     803               
    828804#ifdef CONFIG_UDEBUG
    829805                /*
     
    833809                 * THREAD_B events for threads that already existed
    834810                 * and could be detected with THREAD_READ before.
     811                 *
    835812                 */
    836                 udebug_thread_b_event_attach(t, TASK);
     813                udebug_thread_b_event_attach(thread, TASK);
    837814#else
    838                 thread_attach(t, TASK);
    839 #endif
    840                 thread_ready(t);
    841 
     815                thread_attach(thread, TASK);
     816#endif
     817                thread_ready(thread);
     818               
    842819                return 0;
    843820        } else
    844821                free(kernel_uarg);
    845 
     822       
    846823        return (unative_t) ENOMEM;
    847824}
     
    853830{
    854831        thread_exit();
     832       
    855833        /* Unreachable */
    856834        return 0;
     
    863841 *
    864842 * @return 0 on success or an error code from @ref errno.h.
     843 *
    865844 */
    866845unative_t sys_thread_get_id(thread_id_t *uspace_thread_id)
     
    869848         * No need to acquire lock on THREAD because tid
    870849         * remains constant for the lifespan of the thread.
     850         *
    871851         */
    872852        return (unative_t) copy_to_uspace(uspace_thread_id, &THREAD->tid,
Note: See TracChangeset for help on using the changeset viewer.