Ignore:
File:
1 edited

Legend:

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

    r481d4751 ree42e43  
    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 
    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                  /*
     195                irq_spinlock_lock(&CPU->lock, false);
     196                CPU->idle = true;
     197                irq_spinlock_unlock(&CPU->lock, false);
     198                interrupts_enable();
     199               
     200                /*
    204201                 * An interrupt might occur right now and wake up a thread.
    205202                 * In such case, the CPU will continue to go to sleep
    206203                 * even though there is a runnable thread.
    207204                 */
    208                  cpu_sleep();
    209                  interrupts_disable();
    210                  goto loop;
    211         }
    212        
     205                cpu_sleep();
     206                interrupts_disable();
     207                goto loop;
     208        }
     209       
     210        unsigned int i;
    213211        for (i = 0; i < RQ_COUNT; i++) {
    214                 r = &CPU->rq[i];
    215                 spinlock_lock(&r->lock);
    216                 if (r->n == 0) {
     212                irq_spinlock_lock(&(CPU->rq[i].lock), false);
     213                if (CPU->rq[i].n == 0) {
    217214                        /*
    218215                         * If this queue is empty, try a lower-priority queue.
    219216                         */
    220                         spinlock_unlock(&r->lock);
     217                        irq_spinlock_unlock(&(CPU->rq[i].lock), false);
    221218                        continue;
    222219                }
    223 
     220               
    224221                atomic_dec(&CPU->nrdy);
    225222                atomic_dec(&nrdy);
    226                 r->n--;
    227 
     223                CPU->rq[i].n--;
     224               
    228225                /*
    229226                 * Take the first thread from the queue.
    230227                 */
    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 
     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               
    242238                /*
    243239                 * Clear the THREAD_FLAG_STOLEN flag so that t can be migrated
    244240                 * when load balancing needs emerge.
    245241                 */
    246                 t->flags &= ~THREAD_FLAG_STOLEN;
    247                 spinlock_unlock(&t->lock);
    248 
    249                 return t;
    250         }
     242                thread->flags &= ~THREAD_FLAG_STOLEN;
     243                irq_spinlock_unlock(&thread->lock, false);
     244               
     245                return thread;
     246        }
     247       
    251248        goto loop;
    252 
    253249}
    254250
     
    267263{
    268264        link_t head;
    269         runq_t *r;
    270         int i, n;
    271 
     265       
    272266        list_initialize(&head);
    273         spinlock_lock(&CPU->lock);
     267        irq_spinlock_lock(&CPU->lock, false);
     268       
    274269        if (CPU->needs_relink > NEEDS_RELINK_MAX) {
     270                int i;
    275271                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);
     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);
    290286                }
     287               
    291288                CPU->needs_relink = 0;
    292289        }
    293         spinlock_unlock(&CPU->lock);
    294 
     290       
     291        irq_spinlock_unlock(&CPU->lock, false);
    295292}
    296293
     
    305302{
    306303        volatile ipl_t ipl;
    307 
     304       
    308305        ASSERT(CPU != NULL);
    309 
     306       
    310307        ipl = interrupts_disable();
    311 
     308       
    312309        if (atomic_get(&haltstate))
    313310                halt();
    314311       
    315312        if (THREAD) {
    316                 spinlock_lock(&THREAD->lock);
     313                irq_spinlock_lock(&THREAD->lock, false);
    317314               
    318315                /* Update thread kernel accounting */
     
    330327                        THREAD->last_cycle = get_cycle();
    331328                       
    332                         spinlock_unlock(&THREAD->lock);
     329                        irq_spinlock_unlock(&THREAD->lock, false);
    333330                        interrupts_restore(THREAD->saved_context.ipl);
    334331                       
    335332                        return;
    336333                }
    337 
     334               
    338335                /*
    339336                 * Interrupt priority level of preempted thread is recorded
    340337                 * here to facilitate scheduler() invocations from
    341                  * interrupts_disable()'d code (e.g. waitq_sleep_timeout()).
     338                 * interrupts_disable()'d code (e.g. waitq_sleep_timeout()).
     339                 *
    342340                 */
    343341                THREAD->saved_context.ipl = ipl;
    344342        }
    345 
     343       
    346344        /*
    347345         * Through the 'THE' structure, we keep track of THREAD, TASK, CPU, VM
    348346         * and preemption counter. At this point THE could be coming either
    349347         * from THREAD's or CPU's stack.
     348         *
    350349         */
    351350        the_copy(THE, (the_t *) CPU->stack);
    352 
     351       
    353352        /*
    354353         * We may not keep the old stack.
     
    362361         * Therefore the scheduler() function continues in
    363362         * 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         /* not reached */
     369       
     370        /* Not reached */
    370371}
    371372
     
    376377 * switch to a new thread.
    377378 *
    378  * Assume THREAD->lock is held.
    379379 */
    380380void scheduler_separated_stack(void)
    381381{
    382         int priority;
    383382        DEADLOCK_PROBE_INIT(p_joinwq);
    384383        task_t *old_task = TASK;
    385384        as_t *old_as = AS;
    386 
     385       
     386        ASSERT((!THREAD) || (irq_spinlock_locked(&THREAD->lock)));
    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         *
    393394         */
    394395        if (old_task)
    395396                task_hold(old_task);
     397       
    396398        if (old_as)
    397399                as_hold(old_as);
    398 
     400       
    399401        if (THREAD) {
    400                 /* must be run after the switch to scheduler stack */
     402                /* Must be run after the switch to scheduler stack */
    401403                after_thread_ran();
    402 
     404               
    403405                switch (THREAD->state) {
    404406                case Running:
    405                         spinlock_unlock(&THREAD->lock);
     407                        irq_spinlock_unlock(&THREAD->lock, false);
    406408                        thread_ready(THREAD);
    407409                        break;
    408 
     410               
    409411                case Exiting:
    410412repeat:
    411413                        if (THREAD->detached) {
    412                                 thread_destroy(THREAD);
     414                                thread_destroy(THREAD, false);
    413415                        } else {
    414416                                /*
    415417                                 * The thread structure is kept allocated until
    416418                                 * somebody calls thread_detach() on it.
     419                                 *
    417420                                 */
    418                                 if (!spinlock_trylock(&THREAD->join_wq.lock)) {
     421                                if (!irq_spinlock_trylock(&THREAD->join_wq.lock)) {
    419422                                        /*
    420423                                         * Avoid deadlock.
     424                                         *
    421425                                         */
    422                                         spinlock_unlock(&THREAD->lock);
     426                                        irq_spinlock_unlock(&THREAD->lock, false);
    423427                                        delay(HZ);
    424                                         spinlock_lock(&THREAD->lock);
     428                                        irq_spinlock_lock(&THREAD->lock, false);
    425429                                        DEADLOCK_PROBE(p_joinwq,
    426430                                            DEADLOCK_THRESHOLD);
     
    429433                                _waitq_wakeup_unsafe(&THREAD->join_wq,
    430434                                    WAKEUP_FIRST);
    431                                 spinlock_unlock(&THREAD->join_wq.lock);
     435                                irq_spinlock_unlock(&THREAD->join_wq.lock, false);
    432436                               
    433437                                THREAD->state = Lingering;
    434                                 spinlock_unlock(&THREAD->lock);
     438                                irq_spinlock_unlock(&THREAD->lock, false);
    435439                        }
    436440                        break;
     
    439443                        /*
    440444                         * Prefer the thread after it's woken up.
     445                         *
    441446                         */
    442447                        THREAD->priority = -1;
    443 
     448                       
    444449                        /*
    445450                         * We need to release wq->lock which we locked in
    446451                         * waitq_sleep(). Address of wq->lock is kept in
    447452                         * THREAD->sleep_queue.
     453                         *
    448454                         */
    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 
     455                        irq_spinlock_unlock(&THREAD->sleep_queue->lock, false);
     456                       
     457                        irq_spinlock_unlock(&THREAD->lock, false);
    463458                        break;
    464 
     459               
    465460                default:
    466461                        /*
    467462                         * Entering state is unexpected.
     463                         *
    468464                         */
    469465                        panic("tid%" PRIu64 ": unexpected state %s.",
     
    471467                        break;
    472468                }
    473 
     469               
    474470                THREAD = NULL;
    475471        }
    476 
     472       
    477473        THREAD = find_best_thread();
    478474       
    479         spinlock_lock(&THREAD->lock);
    480         priority = THREAD->priority;
    481         spinlock_unlock(&THREAD->lock);
    482 
    483         relink_rq(priority);           
    484 
     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       
    485481        /*
    486482         * If both the old and the new task are the same, lots of work is
    487483         * avoided.
     484         *
    488485         */
    489486        if (TASK != THREAD->task) {
     
    493490                 * Note that it is possible for two tasks to share one address
    494491                 * space.
     492                 (
    495493                 */
    496494                if (old_as != new_as) {
     
    498496                         * Both tasks and address spaces are different.
    499497                         * Replace the old one with the new one.
     498                         *
    500499                         */
    501500                        as_switch(old_as, new_as);
    502501                }
    503 
     502               
    504503                TASK = THREAD->task;
    505504                before_task_runs();
    506505        }
    507 
     506       
    508507        if (old_task)
    509508                task_release(old_task);
     509       
    510510        if (old_as)
    511511                as_release(old_as);
    512512       
    513         spinlock_lock(&THREAD->lock);   
     513        irq_spinlock_lock(&THREAD->lock, false);
    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         *
    529530         */
    530531        before_thread_runs();
    531 
     532       
    532533        /*
    533534         * Copy the knowledge of CPU, TASK, THREAD and preemption counter to
    534535         * thread's stack.
     536         *
    535537         */
    536538        the_copy(THE, (the_t *) THREAD->kstack);
    537539       
    538540        context_restore(&THREAD->saved_context);
    539         /* not reached */
     541       
     542        /* Not reached */
    540543}
    541544
     
    551554void kcpulb(void *arg)
    552555{
    553         thread_t *t;
    554         int count;
    555556        atomic_count_t average;
    556         unsigned int i;
    557         int j;
    558         int k = 0;
    559         ipl_t ipl;
    560 
     557        atomic_count_t rdy;
     558       
    561559        /*
    562560         * Detach kcpulb as nobody will call thread_join_timeout() on it.
     
    569567         */
    570568        thread_sleep(1);
    571 
     569       
    572570not_satisfied:
    573571        /*
     
    575573         * other CPU's. Note that situation can have changed between two
    576574         * passes. Each time get the most up to date counts.
     575         *
    577576         */
    578577        average = atomic_get(&nrdy) / config.cpu_active + 1;
    579         count = average - atomic_get(&CPU->nrdy);
    580 
    581         if (count <= 0)
     578        rdy = atomic_get(&CPU->nrdy);
     579       
     580        if (average <= rdy)
    582581                goto satisfied;
    583 
     582       
     583        atomic_count_t count = average - rdy;
     584       
    584585        /*
    585586         * Searching least priority queues on all CPU's first and most priority
    586587         * 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 
     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                       
    596598                        /*
    597599                         * Not interested in ourselves.
    598600                         * Doesn't require interrupt disabling for kcpulb has
    599601                         * THREAD_FLAG_WIRED.
     602                         *
    600603                         */
    601604                        if (CPU == cpu)
    602605                                continue;
     606                       
    603607                        if (atomic_get(&cpu->nrdy) <= average)
    604608                                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);
     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);
    612613                                continue;
    613614                        }
    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);
     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                               
    619624                                /*
    620625                                 * We don't want to steal CPU-wired threads
     
    624629                                 * steal threads whose FPU context is still in
    625630                                 * CPU.
     631                                 *
    626632                                 */
    627                                 spinlock_lock(&t->lock);
    628                                 if ((!(t->flags & (THREAD_FLAG_WIRED |
    629                                     THREAD_FLAG_STOLEN))) &&
    630                                     (!(t->fpu_context_engaged))) {
     633                                irq_spinlock_lock(&thread->lock, false);
     634                               
     635                                if ((!(thread->flags & (THREAD_FLAG_WIRED | THREAD_FLAG_STOLEN)))
     636                                    && (!(thread->fpu_context_engaged))) {
    631637                                        /*
    632                                          * Remove t from r.
     638                                         * Remove thread from ready queue.
    633639                                         */
    634                                         spinlock_unlock(&t->lock);
     640                                        irq_spinlock_unlock(&thread->lock, false);
    635641                                       
    636642                                        atomic_dec(&cpu->nrdy);
    637643                                        atomic_dec(&nrdy);
    638 
    639                                         r->n--;
    640                                         list_remove(&t->rq_link);
    641 
     644                                       
     645                                        cpu->rq[rq].n--;
     646                                        list_remove(&thread->rq_link);
     647                                       
    642648                                        break;
    643649                                }
    644                                 spinlock_unlock(&t->lock);
    645                                 l = l->prev;
    646                                 t = NULL;
     650                               
     651                                irq_spinlock_unlock(&thread->lock, false);
     652                               
     653                                link = link->prev;
     654                                thread = NULL;
    647655                        }
    648                         spinlock_unlock(&r->lock);
    649 
    650                         if (t) {
     656                       
     657                        if (thread) {
    651658                                /*
    652                                  * Ready t on local CPU
     659                                 * Ready thread on local CPU
     660                                 *
    653661                                 */
    654                                 spinlock_lock(&t->lock);
     662                               
     663                                irq_spinlock_pass(&(cpu->rq[rq].lock), &thread->lock);
     664                               
    655665#ifdef KCPULB_VERBOSE
    656666                                printf("kcpulb%u: TID %" PRIu64 " -> cpu%u, "
     
    659669                                    atomic_get(&nrdy) / config.cpu_active);
    660670#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        
     671                               
     672                                thread->flags |= THREAD_FLAG_STOLEN;
     673                                thread->state = Entering;
     674                               
     675                                irq_spinlock_unlock(&thread->lock, true);
     676                                thread_ready(thread);
     677                               
    669678                                if (--count == 0)
    670679                                        goto satisfied;
    671                                        
     680                               
    672681                                /*
    673682                                 * We are not satisfied yet, focus on another
    674683                                 * CPU next time.
     684                                 *
    675685                                 */
    676                                 k++;
     686                                acpu_bias++;
    677687                               
    678688                                continue;
    679                         }
    680                         interrupts_restore(ipl);
     689                        } else
     690                                irq_spinlock_unlock(&(cpu->rq[rq].lock), true);
     691                       
    681692                }
    682693        }
    683 
     694       
    684695        if (atomic_get(&CPU->nrdy)) {
    685696                /*
    686697                 * Be a little bit light-weight and let migrated threads run.
     698                 *
    687699                 */
    688700                scheduler();
     
    691703                 * We failed to migrate a single thread.
    692704                 * Give up this turn.
     705                 *
    693706                 */
    694707                goto loop;
    695708        }
    696                
     709       
    697710        goto not_satisfied;
    698 
     711       
    699712satisfied:
    700713        goto loop;
    701714}
    702 
    703715#endif /* CONFIG_SMP */
    704716
    705 
    706 /** Print information about threads & scheduler queues */
     717/** Print information about threads & scheduler queues
     718 *
     719 */
    707720void sched_print_list(void)
    708721{
    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();
     722        size_t cpu;
    718723        for (cpu = 0; cpu < config.cpu_count; cpu++) {
    719 
    720724                if (!cpus[cpu].active)
    721725                        continue;
    722 
    723                 spinlock_lock(&cpus[cpu].lock);
     726               
     727                irq_spinlock_lock(&cpus[cpu].lock, true);
     728               
    724729                printf("cpu%u: address=%p, nrdy=%ld, needs_relink=%" PRIs "\n",
    725730                    cpus[cpu].id, &cpus[cpu], atomic_get(&cpus[cpu].nrdy),
    726731                    cpus[cpu].needs_relink);
    727732               
     733                unsigned int i;
    728734                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);
     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);
    733738                                continue;
    734739                        }
     740                       
    735741                        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]);
     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]);
    741749                        }
    742750                        printf("\n");
    743                         spinlock_unlock(&r->lock);
     751                       
     752                        irq_spinlock_unlock(&(cpus[cpu].rq[i].lock), false);
    744753                }
    745                 spinlock_unlock(&cpus[cpu].lock);
    746         }
    747        
    748         interrupts_restore(ipl);
     754               
     755                irq_spinlock_unlock(&cpus[cpu].lock, true);
     756        }
    749757}
    750758
Note: See TracChangeset for help on using the changeset viewer.