Changeset da1bafb in mainline for kernel/generic/src/proc/scheduler.c


Ignore:
Timestamp:
2010-05-24T18:57:31Z (14 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
File:
1 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
Note: See TracChangeset for help on using the changeset viewer.