Ignore:
File:
1 edited

Legend:

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

    r481d4751 r2d3ddad  
    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
     
    376379 * switch to a new thread.
    377380 *
    378  * Assume THREAD->lock is held.
    379381 */
    380382void scheduler_separated_stack(void)
    381383{
    382         int priority;
    383384        DEADLOCK_PROBE_INIT(p_joinwq);
    384385        task_t *old_task = TASK;
    385386        as_t *old_as = AS;
    386 
     387       
     388        ASSERT(!THREAD || irq_spinlock_locked(&THREAD->lock));
    387389        ASSERT(CPU != NULL);
    388390       
     
    391393         * possible destruction should thread_destroy() be called on this or any
    392394         * other processor while the scheduler is still using them.
     395         *
    393396         */
    394397        if (old_task)
    395398                task_hold(old_task);
     399       
    396400        if (old_as)
    397401                as_hold(old_as);
    398 
     402       
    399403        if (THREAD) {
    400                 /* must be run after the switch to scheduler stack */
     404                /* Must be run after the switch to scheduler stack */
    401405                after_thread_ran();
    402 
     406               
    403407                switch (THREAD->state) {
    404408                case Running:
    405                         spinlock_unlock(&THREAD->lock);
     409                        irq_spinlock_unlock(&THREAD->lock, false);
    406410                        thread_ready(THREAD);
    407411                        break;
    408 
     412               
    409413                case Exiting:
    410414repeat:
    411415                        if (THREAD->detached) {
    412                                 thread_destroy(THREAD);
     416                                thread_destroy(THREAD, false);
    413417                        } else {
    414418                                /*
    415419                                 * The thread structure is kept allocated until
    416420                                 * somebody calls thread_detach() on it.
     421                                 *
    417422                                 */
    418                                 if (!spinlock_trylock(&THREAD->join_wq.lock)) {
     423                                if (!irq_spinlock_trylock(&THREAD->join_wq.lock)) {
    419424                                        /*
    420425                                         * Avoid deadlock.
     426                                         *
    421427                                         */
    422                                         spinlock_unlock(&THREAD->lock);
     428                                        irq_spinlock_unlock(&THREAD->lock, false);
    423429                                        delay(HZ);
    424                                         spinlock_lock(&THREAD->lock);
     430                                        irq_spinlock_lock(&THREAD->lock, false);
    425431                                        DEADLOCK_PROBE(p_joinwq,
    426432                                            DEADLOCK_THRESHOLD);
     
    429435                                _waitq_wakeup_unsafe(&THREAD->join_wq,
    430436                                    WAKEUP_FIRST);
    431                                 spinlock_unlock(&THREAD->join_wq.lock);
     437                                irq_spinlock_unlock(&THREAD->join_wq.lock, false);
    432438                               
    433439                                THREAD->state = Lingering;
    434                                 spinlock_unlock(&THREAD->lock);
     440                                irq_spinlock_unlock(&THREAD->lock, false);
    435441                        }
    436442                        break;
     
    439445                        /*
    440446                         * Prefer the thread after it's woken up.
     447                         *
    441448                         */
    442449                        THREAD->priority = -1;
    443 
     450                       
    444451                        /*
    445452                         * We need to release wq->lock which we locked in
    446453                         * waitq_sleep(). Address of wq->lock is kept in
    447454                         * THREAD->sleep_queue.
     455                         *
    448456                         */
    449                         spinlock_unlock(&THREAD->sleep_queue->lock);
    450 
     457                        irq_spinlock_unlock(&THREAD->sleep_queue->lock, false);
     458                       
    451459                        /*
    452460                         * Check for possible requests for out-of-context
    453461                         * invocation.
     462                         *
    454463                         */
    455464                        if (THREAD->call_me) {
     
    458467                                THREAD->call_me_with = NULL;
    459468                        }
    460 
    461                         spinlock_unlock(&THREAD->lock);
    462 
     469                       
     470                        irq_spinlock_unlock(&THREAD->lock, false);
     471                       
    463472                        break;
    464 
     473               
    465474                default:
    466475                        /*
    467476                         * Entering state is unexpected.
     477                         *
    468478                         */
    469479                        panic("tid%" PRIu64 ": unexpected state %s.",
     
    471481                        break;
    472482                }
    473 
     483               
    474484                THREAD = NULL;
    475485        }
    476 
     486       
    477487        THREAD = find_best_thread();
    478488       
    479         spinlock_lock(&THREAD->lock);
    480         priority = THREAD->priority;
    481         spinlock_unlock(&THREAD->lock);
    482 
    483         relink_rq(priority);           
    484 
     489        irq_spinlock_lock(&THREAD->lock, false);
     490        int priority = THREAD->priority;
     491        irq_spinlock_unlock(&THREAD->lock, false);
     492       
     493        relink_rq(priority);
     494       
    485495        /*
    486496         * If both the old and the new task are the same, lots of work is
    487497         * avoided.
     498         *
    488499         */
    489500        if (TASK != THREAD->task) {
     
    493504                 * Note that it is possible for two tasks to share one address
    494505                 * space.
     506                 (
    495507                 */
    496508                if (old_as != new_as) {
     
    498510                         * Both tasks and address spaces are different.
    499511                         * Replace the old one with the new one.
     512                         *
    500513                         */
    501514                        as_switch(old_as, new_as);
    502515                }
    503 
     516               
    504517                TASK = THREAD->task;
    505518                before_task_runs();
    506519        }
    507 
     520       
    508521        if (old_task)
    509522                task_release(old_task);
     523       
    510524        if (old_as)
    511525                as_release(old_as);
    512526       
    513         spinlock_lock(&THREAD->lock);   
     527        irq_spinlock_lock(&THREAD->lock, false);
    514528        THREAD->state = Running;
    515 
     529       
    516530#ifdef SCHEDULER_VERBOSE
    517531        printf("cpu%u: tid %" PRIu64 " (priority=%d, ticks=%" PRIu64
    518532            ", nrdy=%ld)\n", CPU->id, THREAD->tid, THREAD->priority,
    519533            THREAD->ticks, atomic_get(&CPU->nrdy));
    520 #endif 
    521 
     534#endif
     535       
    522536        /*
    523537         * Some architectures provide late kernel PA2KA(identity)
     
    527541         * necessary, is to be mapped in before_thread_runs(). This
    528542         * function must be executed before the switch to the new stack.
     543         *
    529544         */
    530545        before_thread_runs();
    531 
     546       
    532547        /*
    533548         * Copy the knowledge of CPU, TASK, THREAD and preemption counter to
    534549         * thread's stack.
     550         *
    535551         */
    536552        the_copy(THE, (the_t *) THREAD->kstack);
    537553       
    538554        context_restore(&THREAD->saved_context);
    539         /* not reached */
     555       
     556        /* Not reached */
    540557}
    541558
     
    551568void kcpulb(void *arg)
    552569{
    553         thread_t *t;
    554         int count;
    555570        atomic_count_t average;
    556         unsigned int i;
    557         int j;
    558         int k = 0;
    559         ipl_t ipl;
    560 
     571        atomic_count_t rdy;
     572       
    561573        /*
    562574         * Detach kcpulb as nobody will call thread_join_timeout() on it.
     
    569581         */
    570582        thread_sleep(1);
    571 
     583       
    572584not_satisfied:
    573585        /*
     
    575587         * other CPU's. Note that situation can have changed between two
    576588         * passes. Each time get the most up to date counts.
     589         *
    577590         */
    578591        average = atomic_get(&nrdy) / config.cpu_active + 1;
    579         count = average - atomic_get(&CPU->nrdy);
    580 
    581         if (count <= 0)
     592        rdy = atomic_get(&CPU->nrdy);
     593       
     594        if (average <= rdy)
    582595                goto satisfied;
    583 
     596       
     597        atomic_count_t count = average - rdy;
     598       
    584599        /*
    585600         * Searching least priority queues on all CPU's first and most priority
    586601         * 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 
     602         *
     603         */
     604        size_t acpu;
     605        size_t acpu_bias = 0;
     606        int rq;
     607       
     608        for (rq = RQ_COUNT - 1; rq >= 0; rq--) {
     609                for (acpu = 0; acpu < config.cpu_active; acpu++) {
     610                        cpu_t *cpu = &cpus[(acpu + acpu_bias) % config.cpu_active];
     611                       
    596612                        /*
    597613                         * Not interested in ourselves.
    598614                         * Doesn't require interrupt disabling for kcpulb has
    599615                         * THREAD_FLAG_WIRED.
     616                         *
    600617                         */
    601618                        if (CPU == cpu)
    602619                                continue;
     620                       
    603621                        if (atomic_get(&cpu->nrdy) <= average)
    604622                                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);
     623                       
     624                        irq_spinlock_lock(&(cpu->rq[rq].lock), true);
     625                        if (cpu->rq[rq].n == 0) {
     626                                irq_spinlock_unlock(&(cpu->rq[rq].lock), true);
    612627                                continue;
    613628                        }
    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);
     629                       
     630                        thread_t *thread = NULL;
     631                       
     632                        /* Search rq from the back */
     633                        link_t *link = cpu->rq[rq].rq_head.prev;
     634                       
     635                        while (link != &(cpu->rq[rq].rq_head)) {
     636                                thread = (thread_t *) list_get_instance(link, thread_t, rq_link);
     637                               
    619638                                /*
    620639                                 * We don't want to steal CPU-wired threads
     
    624643                                 * steal threads whose FPU context is still in
    625644                                 * CPU.
     645                                 *
    626646                                 */
    627                                 spinlock_lock(&t->lock);
    628                                 if ((!(t->flags & (THREAD_FLAG_WIRED |
    629                                     THREAD_FLAG_STOLEN))) &&
    630                                     (!(t->fpu_context_engaged))) {
     647                                irq_spinlock_lock(&thread->lock, false);
     648                               
     649                                if ((!(thread->flags & (THREAD_FLAG_WIRED | THREAD_FLAG_STOLEN)))
     650                                    && (!(thread->fpu_context_engaged))) {
    631651                                        /*
    632                                          * Remove t from r.
     652                                         * Remove thread from ready queue.
    633653                                         */
    634                                         spinlock_unlock(&t->lock);
     654                                        irq_spinlock_unlock(&thread->lock, false);
    635655                                       
    636656                                        atomic_dec(&cpu->nrdy);
    637657                                        atomic_dec(&nrdy);
    638 
    639                                         r->n--;
    640                                         list_remove(&t->rq_link);
    641 
     658                                       
     659                                        cpu->rq[rq].n--;
     660                                        list_remove(&thread->rq_link);
     661                                       
    642662                                        break;
    643663                                }
    644                                 spinlock_unlock(&t->lock);
    645                                 l = l->prev;
    646                                 t = NULL;
     664                               
     665                                irq_spinlock_unlock(&thread->lock, false);
     666                               
     667                                link = link->prev;
     668                                thread = NULL;
    647669                        }
    648                         spinlock_unlock(&r->lock);
    649 
    650                         if (t) {
     670                       
     671                        if (thread) {
    651672                                /*
    652                                  * Ready t on local CPU
     673                                 * Ready thread on local CPU
     674                                 *
    653675                                 */
    654                                 spinlock_lock(&t->lock);
     676                               
     677                                irq_spinlock_pass(&(cpu->rq[rq].lock), &thread->lock);
     678                               
    655679#ifdef KCPULB_VERBOSE
    656680                                printf("kcpulb%u: TID %" PRIu64 " -> cpu%u, "
     
    659683                                    atomic_get(&nrdy) / config.cpu_active);
    660684#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        
     685                               
     686                                thread->flags |= THREAD_FLAG_STOLEN;
     687                                thread->state = Entering;
     688                               
     689                                irq_spinlock_unlock(&thread->lock, true);
     690                                thread_ready(thread);
     691                               
    669692                                if (--count == 0)
    670693                                        goto satisfied;
    671                                        
     694                               
    672695                                /*
    673696                                 * We are not satisfied yet, focus on another
    674697                                 * CPU next time.
     698                                 *
    675699                                 */
    676                                 k++;
     700                                acpu_bias++;
    677701                               
    678702                                continue;
    679                         }
    680                         interrupts_restore(ipl);
     703                        } else
     704                                irq_spinlock_unlock(&(cpu->rq[rq].lock), true);
     705                       
    681706                }
    682707        }
    683 
     708       
    684709        if (atomic_get(&CPU->nrdy)) {
    685710                /*
    686711                 * Be a little bit light-weight and let migrated threads run.
     712                 *
    687713                 */
    688714                scheduler();
     
    691717                 * We failed to migrate a single thread.
    692718                 * Give up this turn.
     719                 *
    693720                 */
    694721                goto loop;
    695722        }
    696                
     723       
    697724        goto not_satisfied;
    698 
     725       
    699726satisfied:
    700727        goto loop;
    701728}
    702 
    703729#endif /* CONFIG_SMP */
    704730
    705 
    706 /** Print information about threads & scheduler queues */
     731/** Print information about threads & scheduler queues
     732 *
     733 */
    707734void sched_print_list(void)
    708735{
    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();
     736        size_t cpu;
    718737        for (cpu = 0; cpu < config.cpu_count; cpu++) {
    719 
    720738                if (!cpus[cpu].active)
    721739                        continue;
    722 
    723                 spinlock_lock(&cpus[cpu].lock);
     740               
     741                irq_spinlock_lock(&cpus[cpu].lock, true);
     742               
    724743                printf("cpu%u: address=%p, nrdy=%ld, needs_relink=%" PRIs "\n",
    725744                    cpus[cpu].id, &cpus[cpu], atomic_get(&cpus[cpu].nrdy),
    726745                    cpus[cpu].needs_relink);
    727746               
     747                unsigned int i;
    728748                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);
     749                        irq_spinlock_lock(&(cpus[cpu].rq[i].lock), false);
     750                        if (cpus[cpu].rq[i].n == 0) {
     751                                irq_spinlock_unlock(&(cpus[cpu].rq[i].lock), false);
    733752                                continue;
    734753                        }
     754                       
    735755                        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]);
     756                        link_t *cur;
     757                        for (cur = cpus[cpu].rq[i].rq_head.next;
     758                            cur != &(cpus[cpu].rq[i].rq_head);
     759                            cur = cur->next) {
     760                                thread_t *thread = list_get_instance(cur, thread_t, rq_link);
     761                                printf("%" PRIu64 "(%s) ", thread->tid,
     762                                    thread_states[thread->state]);
    741763                        }
    742764                        printf("\n");
    743                         spinlock_unlock(&r->lock);
     765                       
     766                        irq_spinlock_unlock(&(cpus[cpu].rq[i].lock), false);
    744767                }
    745                 spinlock_unlock(&cpus[cpu].lock);
    746         }
    747        
    748         interrupts_restore(ipl);
     768               
     769                irq_spinlock_unlock(&cpus[cpu].lock, true);
     770        }
    749771}
    750772
Note: See TracChangeset for help on using the changeset viewer.