Ignore:
File:
1 edited

Legend:

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

    ree42e43 r481d4751  
    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         irq_spinlock_lock(&CPU->lock, false);
    126        
     125        spinlock_lock(&CPU->lock);
     126
    127127        /* Save old context */
    128         if (CPU->fpu_owner != NULL) {
    129                 irq_spinlock_lock(&CPU->fpu_owner->lock, false);
     128        if (CPU->fpu_owner != NULL) { 
     129                spinlock_lock(&CPU->fpu_owner->lock);
    130130                fpu_context_save(CPU->fpu_owner->saved_fpu_context);
    131                
    132                 /* Don't prevent migration */
     131                /* don't prevent migration */
    133132                CPU->fpu_owner->fpu_context_engaged = 0;
    134                 irq_spinlock_unlock(&CPU->fpu_owner->lock, false);
     133                spinlock_unlock(&CPU->fpu_owner->lock);
    135134                CPU->fpu_owner = NULL;
    136135        }
    137        
    138         irq_spinlock_lock(&THREAD->lock, false);
     136
     137        spinlock_lock(&THREAD->lock);
    139138        if (THREAD->fpu_context_exists) {
    140139                fpu_context_restore(THREAD->saved_fpu_context);
     
    143142                if (!THREAD->saved_fpu_context) {
    144143                        /* Might sleep */
    145                         irq_spinlock_unlock(&THREAD->lock, false);
    146                         irq_spinlock_unlock(&CPU->lock, false);
     144                        spinlock_unlock(&THREAD->lock);
     145                        spinlock_unlock(&CPU->lock);
    147146                        THREAD->saved_fpu_context =
    148147                            (fpu_context_t *) slab_alloc(fpu_context_slab, 0);
    149                        
    150148                        /* We may have switched CPUs during slab_alloc */
    151                         goto restart;
     149                        goto restart; 
    152150                }
    153151                fpu_init();
    154152                THREAD->fpu_context_exists = 1;
    155153        }
    156        
    157154        CPU->fpu_owner = THREAD;
    158155        THREAD->fpu_context_engaged = 1;
    159         irq_spinlock_unlock(&THREAD->lock, false);
    160        
    161         irq_spinlock_unlock(&CPU->lock, false);
    162 }
    163 #endif /* CONFIG_FPU_LAZY */
     156        spinlock_unlock(&THREAD->lock);
     157
     158        spinlock_unlock(&CPU->lock);
     159}
     160#endif
    164161
    165162/** Initialize scheduler
     
    183180static thread_t *find_best_thread(void)
    184181{
     182        thread_t *t;
     183        runq_t *r;
     184        int i;
     185
    185186        ASSERT(CPU != NULL);
    186        
     187
    187188loop:
    188189       
     
    193194                 * This improves energy saving and hyperthreading.
    194195                 */
    195                 irq_spinlock_lock(&CPU->lock, false);
    196                 CPU->idle = true;
    197                 irq_spinlock_unlock(&CPU->lock, false);
    198                 interrupts_enable();
    199                
    200                 /*
     196
     197                 /* 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                 /*
    201204                 * An interrupt might occur right now and wake up a thread.
    202205                 * In such case, the CPU will continue to go to sleep
    203206                 * even though there is a runnable thread.
    204207                 */
    205                 cpu_sleep();
    206                 interrupts_disable();
    207                 goto loop;
    208         }
    209        
    210         unsigned int i;
     208                 cpu_sleep();
     209                 interrupts_disable();
     210                 goto loop;
     211        }
     212       
    211213        for (i = 0; i < RQ_COUNT; i++) {
    212                 irq_spinlock_lock(&(CPU->rq[i].lock), false);
    213                 if (CPU->rq[i].n == 0) {
     214                r = &CPU->rq[i];
     215                spinlock_lock(&r->lock);
     216                if (r->n == 0) {
    214217                        /*
    215218                         * If this queue is empty, try a lower-priority queue.
    216219                         */
    217                         irq_spinlock_unlock(&(CPU->rq[i].lock), false);
     220                        spinlock_unlock(&r->lock);
    218221                        continue;
    219222                }
    220                
     223
    221224                atomic_dec(&CPU->nrdy);
    222225                atomic_dec(&nrdy);
    223                 CPU->rq[i].n--;
    224                
     226                r->n--;
     227
    225228                /*
    226229                 * Take the first thread from the queue.
    227230                 */
    228                 thread_t *thread =
    229                     list_get_instance(CPU->rq[i].rq_head.next, thread_t, rq_link);
    230                 list_remove(&thread->rq_link);
    231                
    232                 irq_spinlock_pass(&(CPU->rq[i].lock), &thread->lock);
    233                
    234                 thread->cpu = CPU;
    235                 thread->ticks = us2ticks((i + 1) * 10000);
    236                 thread->priority = i;  /* Correct rq index */
    237                
     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
    238242                /*
    239243                 * Clear the THREAD_FLAG_STOLEN flag so that t can be migrated
    240244                 * when load balancing needs emerge.
    241245                 */
    242                 thread->flags &= ~THREAD_FLAG_STOLEN;
    243                 irq_spinlock_unlock(&thread->lock, false);
    244                
    245                 return thread;
    246         }
    247        
     246                t->flags &= ~THREAD_FLAG_STOLEN;
     247                spinlock_unlock(&t->lock);
     248
     249                return t;
     250        }
    248251        goto loop;
     252
    249253}
    250254
     
    263267{
    264268        link_t head;
    265        
     269        runq_t *r;
     270        int i, n;
     271
    266272        list_initialize(&head);
    267         irq_spinlock_lock(&CPU->lock, false);
    268        
     273        spinlock_lock(&CPU->lock);
    269274        if (CPU->needs_relink > NEEDS_RELINK_MAX) {
    270                 int i;
    271275                for (i = start; i < RQ_COUNT - 1; i++) {
    272                         /* Remember and empty rq[i + 1] */
    273                        
    274                         irq_spinlock_lock(&CPU->rq[i + 1].lock, false);
    275                         list_concat(&head, &CPU->rq[i + 1].rq_head);
    276                         size_t n = CPU->rq[i + 1].n;
    277                         CPU->rq[i + 1].n = 0;
    278                         irq_spinlock_unlock(&CPU->rq[i + 1].lock, false);
    279                        
    280                         /* Append rq[i + 1] to rq[i] */
    281                        
    282                         irq_spinlock_lock(&CPU->rq[i].lock, false);
    283                         list_concat(&CPU->rq[i].rq_head, &head);
    284                         CPU->rq[i].n += n;
    285                         irq_spinlock_unlock(&CPU->rq[i].lock, false);
     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);
    286290                }
    287                
    288291                CPU->needs_relink = 0;
    289292        }
    290        
    291         irq_spinlock_unlock(&CPU->lock, false);
     293        spinlock_unlock(&CPU->lock);
     294
    292295}
    293296
     
    302305{
    303306        volatile ipl_t ipl;
    304        
     307
    305308        ASSERT(CPU != NULL);
    306        
     309
    307310        ipl = interrupts_disable();
    308        
     311
    309312        if (atomic_get(&haltstate))
    310313                halt();
    311314       
    312315        if (THREAD) {
    313                 irq_spinlock_lock(&THREAD->lock, false);
     316                spinlock_lock(&THREAD->lock);
    314317               
    315318                /* Update thread kernel accounting */
     
    327330                        THREAD->last_cycle = get_cycle();
    328331                       
    329                         irq_spinlock_unlock(&THREAD->lock, false);
     332                        spinlock_unlock(&THREAD->lock);
    330333                        interrupts_restore(THREAD->saved_context.ipl);
    331334                       
    332335                        return;
    333336                }
    334                
     337
    335338                /*
    336339                 * Interrupt priority level of preempted thread is recorded
    337340                 * here to facilitate scheduler() invocations from
    338                  * interrupts_disable()'d code (e.g. waitq_sleep_timeout()).
    339                  *
     341                 * interrupts_disable()'d code (e.g. waitq_sleep_timeout()).
    340342                 */
    341343                THREAD->saved_context.ipl = ipl;
    342344        }
    343        
     345
    344346        /*
    345347         * Through the 'THE' structure, we keep track of THREAD, TASK, CPU, VM
    346348         * and preemption counter. At this point THE could be coming either
    347349         * from THREAD's or CPU's stack.
    348          *
    349350         */
    350351        the_copy(THE, (the_t *) CPU->stack);
    351        
     352
    352353        /*
    353354         * We may not keep the old stack.
     
    361362         * Therefore the scheduler() function continues in
    362363         * scheduler_separated_stack().
    363          *
    364364         */
    365365        context_save(&CPU->saved_context);
     
    367367            (uintptr_t) CPU->stack, CPU_STACK_SIZE);
    368368        context_restore(&CPU->saved_context);
    369        
    370         /* Not reached */
     369        /* not reached */
    371370}
    372371
     
    377376 * switch to a new thread.
    378377 *
     378 * Assume THREAD->lock is held.
    379379 */
    380380void scheduler_separated_stack(void)
    381381{
     382        int priority;
    382383        DEADLOCK_PROBE_INIT(p_joinwq);
    383384        task_t *old_task = TASK;
    384385        as_t *old_as = AS;
    385        
    386         ASSERT((!THREAD) || (irq_spinlock_locked(&THREAD->lock)));
     386
    387387        ASSERT(CPU != NULL);
    388388       
     
    391391         * possible destruction should thread_destroy() be called on this or any
    392392         * other processor while the scheduler is still using them.
    393          *
    394393         */
    395394        if (old_task)
    396395                task_hold(old_task);
    397        
    398396        if (old_as)
    399397                as_hold(old_as);
    400        
     398
    401399        if (THREAD) {
    402                 /* Must be run after the switch to scheduler stack */
     400                /* must be run after the switch to scheduler stack */
    403401                after_thread_ran();
    404                
     402
    405403                switch (THREAD->state) {
    406404                case Running:
    407                         irq_spinlock_unlock(&THREAD->lock, false);
     405                        spinlock_unlock(&THREAD->lock);
    408406                        thread_ready(THREAD);
    409407                        break;
    410                
     408
    411409                case Exiting:
    412410repeat:
    413411                        if (THREAD->detached) {
    414                                 thread_destroy(THREAD, false);
     412                                thread_destroy(THREAD);
    415413                        } else {
    416414                                /*
    417415                                 * The thread structure is kept allocated until
    418416                                 * somebody calls thread_detach() on it.
    419                                  *
    420417                                 */
    421                                 if (!irq_spinlock_trylock(&THREAD->join_wq.lock)) {
     418                                if (!spinlock_trylock(&THREAD->join_wq.lock)) {
    422419                                        /*
    423420                                         * Avoid deadlock.
    424                                          *
    425421                                         */
    426                                         irq_spinlock_unlock(&THREAD->lock, false);
     422                                        spinlock_unlock(&THREAD->lock);
    427423                                        delay(HZ);
    428                                         irq_spinlock_lock(&THREAD->lock, false);
     424                                        spinlock_lock(&THREAD->lock);
    429425                                        DEADLOCK_PROBE(p_joinwq,
    430426                                            DEADLOCK_THRESHOLD);
     
    433429                                _waitq_wakeup_unsafe(&THREAD->join_wq,
    434430                                    WAKEUP_FIRST);
    435                                 irq_spinlock_unlock(&THREAD->join_wq.lock, false);
     431                                spinlock_unlock(&THREAD->join_wq.lock);
    436432                               
    437433                                THREAD->state = Lingering;
    438                                 irq_spinlock_unlock(&THREAD->lock, false);
     434                                spinlock_unlock(&THREAD->lock);
    439435                        }
    440436                        break;
     
    443439                        /*
    444440                         * Prefer the thread after it's woken up.
    445                          *
    446441                         */
    447442                        THREAD->priority = -1;
    448                        
     443
    449444                        /*
    450445                         * We need to release wq->lock which we locked in
    451446                         * waitq_sleep(). Address of wq->lock is kept in
    452447                         * THREAD->sleep_queue.
    453                          *
    454448                         */
    455                         irq_spinlock_unlock(&THREAD->sleep_queue->lock, false);
    456                        
    457                         irq_spinlock_unlock(&THREAD->lock, false);
     449                        spinlock_unlock(&THREAD->sleep_queue->lock);
     450
     451                        /*
     452                         * Check for possible requests for out-of-context
     453                         * invocation.
     454                         */
     455                        if (THREAD->call_me) {
     456                                THREAD->call_me(THREAD->call_me_with);
     457                                THREAD->call_me = NULL;
     458                                THREAD->call_me_with = NULL;
     459                        }
     460
     461                        spinlock_unlock(&THREAD->lock);
     462
    458463                        break;
    459                
     464
    460465                default:
    461466                        /*
    462467                         * Entering state is unexpected.
    463                          *
    464468                         */
    465469                        panic("tid%" PRIu64 ": unexpected state %s.",
     
    467471                        break;
    468472                }
    469                
     473
    470474                THREAD = NULL;
    471475        }
    472        
     476
    473477        THREAD = find_best_thread();
    474478       
    475         irq_spinlock_lock(&THREAD->lock, false);
    476         int priority = THREAD->priority;
    477         irq_spinlock_unlock(&THREAD->lock, false);
    478        
    479         relink_rq(priority);
    480        
     479        spinlock_lock(&THREAD->lock);
     480        priority = THREAD->priority;
     481        spinlock_unlock(&THREAD->lock);
     482
     483        relink_rq(priority);           
     484
    481485        /*
    482486         * If both the old and the new task are the same, lots of work is
    483487         * avoided.
    484          *
    485488         */
    486489        if (TASK != THREAD->task) {
     
    490493                 * Note that it is possible for two tasks to share one address
    491494                 * space.
    492                  (
    493495                 */
    494496                if (old_as != new_as) {
     
    496498                         * Both tasks and address spaces are different.
    497499                         * Replace the old one with the new one.
    498                          *
    499500                         */
    500501                        as_switch(old_as, new_as);
    501502                }
    502                
     503
    503504                TASK = THREAD->task;
    504505                before_task_runs();
    505506        }
    506        
     507
    507508        if (old_task)
    508509                task_release(old_task);
    509        
    510510        if (old_as)
    511511                as_release(old_as);
    512512       
    513         irq_spinlock_lock(&THREAD->lock, false);
     513        spinlock_lock(&THREAD->lock);   
    514514        THREAD->state = Running;
    515        
     515
    516516#ifdef SCHEDULER_VERBOSE
    517517        printf("cpu%u: tid %" PRIu64 " (priority=%d, ticks=%" PRIu64
    518518            ", nrdy=%ld)\n", CPU->id, THREAD->tid, THREAD->priority,
    519519            THREAD->ticks, atomic_get(&CPU->nrdy));
    520 #endif
    521        
     520#endif 
     521
    522522        /*
    523523         * Some architectures provide late kernel PA2KA(identity)
     
    527527         * necessary, is to be mapped in before_thread_runs(). This
    528528         * function must be executed before the switch to the new stack.
    529          *
    530529         */
    531530        before_thread_runs();
    532        
     531
    533532        /*
    534533         * Copy the knowledge of CPU, TASK, THREAD and preemption counter to
    535534         * thread's stack.
    536          *
    537535         */
    538536        the_copy(THE, (the_t *) THREAD->kstack);
    539537       
    540538        context_restore(&THREAD->saved_context);
    541        
    542         /* Not reached */
     539        /* not reached */
    543540}
    544541
     
    554551void kcpulb(void *arg)
    555552{
     553        thread_t *t;
     554        int count;
    556555        atomic_count_t average;
    557         atomic_count_t rdy;
    558        
     556        unsigned int i;
     557        int j;
     558        int k = 0;
     559        ipl_t ipl;
     560
    559561        /*
    560562         * Detach kcpulb as nobody will call thread_join_timeout() on it.
     
    567569         */
    568570        thread_sleep(1);
    569        
     571
    570572not_satisfied:
    571573        /*
     
    573575         * other CPU's. Note that situation can have changed between two
    574576         * passes. Each time get the most up to date counts.
    575          *
    576577         */
    577578        average = atomic_get(&nrdy) / config.cpu_active + 1;
    578         rdy = atomic_get(&CPU->nrdy);
    579        
    580         if (average <= rdy)
     579        count = average - atomic_get(&CPU->nrdy);
     580
     581        if (count <= 0)
    581582                goto satisfied;
    582        
    583         atomic_count_t count = average - rdy;
    584        
     583
    585584        /*
    586585         * Searching least priority queues on all CPU's first and most priority
    587586         * queues on all CPU's last.
    588          *
    589          */
    590         size_t acpu;
    591         size_t acpu_bias = 0;
    592         int rq;
    593        
    594         for (rq = RQ_COUNT - 1; rq >= 0; rq--) {
    595                 for (acpu = 0; acpu < config.cpu_active; acpu++) {
    596                         cpu_t *cpu = &cpus[(acpu + acpu_bias) % config.cpu_active];
    597                        
     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
    598596                        /*
    599597                         * Not interested in ourselves.
    600598                         * Doesn't require interrupt disabling for kcpulb has
    601599                         * THREAD_FLAG_WIRED.
    602                          *
    603600                         */
    604601                        if (CPU == cpu)
    605602                                continue;
    606                        
    607603                        if (atomic_get(&cpu->nrdy) <= average)
    608604                                continue;
    609                        
    610                         irq_spinlock_lock(&(cpu->rq[rq].lock), true);
    611                         if (cpu->rq[rq].n == 0) {
    612                                 irq_spinlock_unlock(&(cpu->rq[rq].lock), true);
     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);
    613612                                continue;
    614613                        }
    615                        
    616                         thread_t *thread = NULL;
    617                        
    618                         /* Search rq from the back */
    619                         link_t *link = cpu->rq[rq].rq_head.prev;
    620                        
    621                         while (link != &(cpu->rq[rq].rq_head)) {
    622                                 thread = (thread_t *) list_get_instance(link, thread_t, rq_link);
    623                                
     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);
    624619                                /*
    625620                                 * We don't want to steal CPU-wired threads
     
    629624                                 * steal threads whose FPU context is still in
    630625                                 * CPU.
    631                                  *
    632626                                 */
    633                                 irq_spinlock_lock(&thread->lock, false);
    634                                
    635                                 if ((!(thread->flags & (THREAD_FLAG_WIRED | THREAD_FLAG_STOLEN)))
    636                                     && (!(thread->fpu_context_engaged))) {
     627                                spinlock_lock(&t->lock);
     628                                if ((!(t->flags & (THREAD_FLAG_WIRED |
     629                                    THREAD_FLAG_STOLEN))) &&
     630                                    (!(t->fpu_context_engaged))) {
    637631                                        /*
    638                                          * Remove thread from ready queue.
     632                                         * Remove t from r.
    639633                                         */
    640                                         irq_spinlock_unlock(&thread->lock, false);
     634                                        spinlock_unlock(&t->lock);
    641635                                       
    642636                                        atomic_dec(&cpu->nrdy);
    643637                                        atomic_dec(&nrdy);
    644                                        
    645                                         cpu->rq[rq].n--;
    646                                         list_remove(&thread->rq_link);
    647                                        
     638
     639                                        r->n--;
     640                                        list_remove(&t->rq_link);
     641
    648642                                        break;
    649643                                }
    650                                
    651                                 irq_spinlock_unlock(&thread->lock, false);
    652                                
    653                                 link = link->prev;
    654                                 thread = NULL;
     644                                spinlock_unlock(&t->lock);
     645                                l = l->prev;
     646                                t = NULL;
    655647                        }
    656                        
    657                         if (thread) {
     648                        spinlock_unlock(&r->lock);
     649
     650                        if (t) {
    658651                                /*
    659                                  * Ready thread on local CPU
    660                                  *
     652                                 * Ready t on local CPU
    661653                                 */
    662                                
    663                                 irq_spinlock_pass(&(cpu->rq[rq].lock), &thread->lock);
    664                                
     654                                spinlock_lock(&t->lock);
    665655#ifdef KCPULB_VERBOSE
    666656                                printf("kcpulb%u: TID %" PRIu64 " -> cpu%u, "
     
    669659                                    atomic_get(&nrdy) / config.cpu_active);
    670660#endif
    671                                
    672                                 thread->flags |= THREAD_FLAG_STOLEN;
    673                                 thread->state = Entering;
    674                                
    675                                 irq_spinlock_unlock(&thread->lock, true);
    676                                 thread_ready(thread);
    677                                
     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       
    678669                                if (--count == 0)
    679670                                        goto satisfied;
    680                                
     671                                       
    681672                                /*
    682673                                 * We are not satisfied yet, focus on another
    683674                                 * CPU next time.
    684                                  *
    685675                                 */
    686                                 acpu_bias++;
     676                                k++;
    687677                               
    688678                                continue;
    689                         } else
    690                                 irq_spinlock_unlock(&(cpu->rq[rq].lock), true);
    691                        
     679                        }
     680                        interrupts_restore(ipl);
    692681                }
    693682        }
    694        
     683
    695684        if (atomic_get(&CPU->nrdy)) {
    696685                /*
    697686                 * Be a little bit light-weight and let migrated threads run.
    698                  *
    699687                 */
    700688                scheduler();
     
    703691                 * We failed to migrate a single thread.
    704692                 * Give up this turn.
    705                  *
    706693                 */
    707694                goto loop;
    708695        }
    709        
     696               
    710697        goto not_satisfied;
    711        
     698
    712699satisfied:
    713700        goto loop;
    714701}
     702
    715703#endif /* CONFIG_SMP */
    716704
    717 /** Print information about threads & scheduler queues
    718  *
    719  */
     705
     706/** Print information about threads & scheduler queues */
    720707void sched_print_list(void)
    721708{
    722         size_t cpu;
     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();
    723718        for (cpu = 0; cpu < config.cpu_count; cpu++) {
     719
    724720                if (!cpus[cpu].active)
    725721                        continue;
    726                
    727                 irq_spinlock_lock(&cpus[cpu].lock, true);
    728                
     722
     723                spinlock_lock(&cpus[cpu].lock);
    729724                printf("cpu%u: address=%p, nrdy=%ld, needs_relink=%" PRIs "\n",
    730725                    cpus[cpu].id, &cpus[cpu], atomic_get(&cpus[cpu].nrdy),
    731726                    cpus[cpu].needs_relink);
    732727               
    733                 unsigned int i;
    734728                for (i = 0; i < RQ_COUNT; i++) {
    735                         irq_spinlock_lock(&(cpus[cpu].rq[i].lock), false);
    736                         if (cpus[cpu].rq[i].n == 0) {
    737                                 irq_spinlock_unlock(&(cpus[cpu].rq[i].lock), false);
     729                        r = &cpus[cpu].rq[i];
     730                        spinlock_lock(&r->lock);
     731                        if (!r->n) {
     732                                spinlock_unlock(&r->lock);
    738733                                continue;
    739734                        }
    740                        
    741735                        printf("\trq[%u]: ", i);
    742                         link_t *cur;
    743                         for (cur = cpus[cpu].rq[i].rq_head.next;
    744                             cur != &(cpus[cpu].rq[i].rq_head);
    745                             cur = cur->next) {
    746                                 thread_t *thread = list_get_instance(cur, thread_t, rq_link);
    747                                 printf("%" PRIu64 "(%s) ", thread->tid,
    748                                     thread_states[thread->state]);
     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]);
    749741                        }
    750742                        printf("\n");
    751                        
    752                         irq_spinlock_unlock(&(cpus[cpu].rq[i].lock), false);
     743                        spinlock_unlock(&r->lock);
    753744                }
    754                
    755                 irq_spinlock_unlock(&cpus[cpu].lock, true);
    756         }
     745                spinlock_unlock(&cpus[cpu].lock);
     746        }
     747       
     748        interrupts_restore(ipl);
    757749}
    758750
Note: See TracChangeset for help on using the changeset viewer.