Ignore:
File:
1 edited

Legend:

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

    r7e752b2 r98000fb  
    11/*
    2  * Copyright (c) 2010 Jakub Jermar
     2 * Copyright (c) 2001-2007 Jakub Jermar
    33 * All rights reserved.
    44 *
     
    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:
     189        interrupts_enable();
    188190       
    189191        if (atomic_get(&CPU->nrdy) == 0) {
     
    193195                 * This improves energy saving and hyperthreading.
    194196                 */
    195                 irq_spinlock_lock(&CPU->lock, false);
    196                 CPU->idle = true;
    197                 irq_spinlock_unlock(&CPU->lock, false);
    198                 interrupts_enable();
    199                
     197
    200198                /*
    201199                 * An interrupt might occur right now and wake up a thread.
     
    203201                 * even though there is a runnable thread.
    204202                 */
    205                 cpu_sleep();
    206                 interrupts_disable();
    207                 goto loop;
    208         }
    209        
    210         unsigned int i;
     203
     204                 cpu_sleep();
     205                 goto loop;
     206        }
     207
     208        interrupts_disable();
     209       
    211210        for (i = 0; i < RQ_COUNT; i++) {
    212                 irq_spinlock_lock(&(CPU->rq[i].lock), false);
    213                 if (CPU->rq[i].n == 0) {
     211                r = &CPU->rq[i];
     212                spinlock_lock(&r->lock);
     213                if (r->n == 0) {
    214214                        /*
    215215                         * If this queue is empty, try a lower-priority queue.
    216216                         */
    217                         irq_spinlock_unlock(&(CPU->rq[i].lock), false);
     217                        spinlock_unlock(&r->lock);
    218218                        continue;
    219219                }
    220                
     220
    221221                atomic_dec(&CPU->nrdy);
    222222                atomic_dec(&nrdy);
    223                 CPU->rq[i].n--;
    224                
     223                r->n--;
     224
    225225                /*
    226226                 * Take the first thread from the queue.
    227227                 */
    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                
     228                t = list_get_instance(r->rq_head.next, thread_t, rq_link);
     229                list_remove(&t->rq_link);
     230
     231                spinlock_unlock(&r->lock);
     232
     233                spinlock_lock(&t->lock);
     234                t->cpu = CPU;
     235
     236                t->ticks = us2ticks((i + 1) * 10000);
     237                t->priority = i;        /* correct rq index */
     238
    238239                /*
    239240                 * Clear the THREAD_FLAG_STOLEN flag so that t can be migrated
    240241                 * when load balancing needs emerge.
    241242                 */
    242                 thread->flags &= ~THREAD_FLAG_STOLEN;
    243                 irq_spinlock_unlock(&thread->lock, false);
    244                
    245                 return thread;
    246         }
    247        
     243                t->flags &= ~THREAD_FLAG_STOLEN;
     244                spinlock_unlock(&t->lock);
     245
     246                return t;
     247        }
    248248        goto loop;
     249
    249250}
    250251
     
    263264{
    264265        link_t head;
    265        
     266        runq_t *r;
     267        int i, n;
     268
    266269        list_initialize(&head);
    267         irq_spinlock_lock(&CPU->lock, false);
    268        
     270        spinlock_lock(&CPU->lock);
    269271        if (CPU->needs_relink > NEEDS_RELINK_MAX) {
    270                 int i;
    271272                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);
    286                 }
     273                        /* remember and empty rq[i + 1] */
     274                        r = &CPU->rq[i + 1];
     275                        spinlock_lock(&r->lock);
     276                        list_concat(&head, &r->rq_head);
     277                        n = r->n;
     278                        r->n = 0;
     279                        spinlock_unlock(&r->lock);
    287280               
     281                        /* append rq[i + 1] to rq[i] */
     282                        r = &CPU->rq[i];
     283                        spinlock_lock(&r->lock);
     284                        list_concat(&r->rq_head, &head);
     285                        r->n += n;
     286                        spinlock_unlock(&r->lock);
     287                }
    288288                CPU->needs_relink = 0;
    289289        }
    290        
    291         irq_spinlock_unlock(&CPU->lock, false);
     290        spinlock_unlock(&CPU->lock);
     291
    292292}
    293293
     
    302302{
    303303        volatile ipl_t ipl;
    304        
     304
    305305        ASSERT(CPU != NULL);
    306        
     306
    307307        ipl = interrupts_disable();
    308        
     308
    309309        if (atomic_get(&haltstate))
    310310                halt();
    311311       
    312312        if (THREAD) {
    313                 irq_spinlock_lock(&THREAD->lock, false);
     313                spinlock_lock(&THREAD->lock);
    314314               
    315                 /* Update thread kernel accounting */
    316                 THREAD->kcycles += get_cycle() - THREAD->last_cycle;
     315                /* Update thread accounting */
     316                THREAD->cycles += get_cycle() - THREAD->last_cycle;
    317317               
    318318#ifndef CONFIG_FPU_LAZY
     
    327327                        THREAD->last_cycle = get_cycle();
    328328                       
    329                         irq_spinlock_unlock(&THREAD->lock, false);
     329                        spinlock_unlock(&THREAD->lock);
    330330                        interrupts_restore(THREAD->saved_context.ipl);
    331331                       
    332332                        return;
    333333                }
    334                
     334
    335335                /*
    336336                 * Interrupt priority level of preempted thread is recorded
    337337                 * here to facilitate scheduler() invocations from
    338                  * interrupts_disable()'d code (e.g. waitq_sleep_timeout()).
    339                  *
     338                 * interrupts_disable()'d code (e.g. waitq_sleep_timeout()).
    340339                 */
    341340                THREAD->saved_context.ipl = ipl;
    342341        }
    343        
     342
    344343        /*
    345344         * Through the 'THE' structure, we keep track of THREAD, TASK, CPU, VM
    346345         * and preemption counter. At this point THE could be coming either
    347346         * from THREAD's or CPU's stack.
    348          *
    349347         */
    350348        the_copy(THE, (the_t *) CPU->stack);
    351        
     349
    352350        /*
    353351         * We may not keep the old stack.
     
    361359         * Therefore the scheduler() function continues in
    362360         * scheduler_separated_stack().
    363          *
    364361         */
    365362        context_save(&CPU->saved_context);
     
    367364            (uintptr_t) CPU->stack, CPU_STACK_SIZE);
    368365        context_restore(&CPU->saved_context);
    369        
    370         /* Not reached */
     366        /* not reached */
    371367}
    372368
     
    377373 * switch to a new thread.
    378374 *
     375 * Assume THREAD->lock is held.
    379376 */
    380377void scheduler_separated_stack(void)
    381378{
     379        int priority;
    382380        DEADLOCK_PROBE_INIT(p_joinwq);
    383         task_t *old_task = TASK;
    384         as_t *old_as = AS;
    385        
    386         ASSERT((!THREAD) || (irq_spinlock_locked(&THREAD->lock)));
     381
    387382        ASSERT(CPU != NULL);
    388383       
    389         /*
    390          * Hold the current task and the address space to prevent their
    391          * possible destruction should thread_destroy() be called on this or any
    392          * other processor while the scheduler is still using them.
    393          *
    394          */
    395         if (old_task)
    396                 task_hold(old_task);
    397        
    398         if (old_as)
    399                 as_hold(old_as);
    400        
    401384        if (THREAD) {
    402                 /* Must be run after the switch to scheduler stack */
     385                /* must be run after the switch to scheduler stack */
    403386                after_thread_ran();
    404                
     387
    405388                switch (THREAD->state) {
    406389                case Running:
    407                         irq_spinlock_unlock(&THREAD->lock, false);
     390                        spinlock_unlock(&THREAD->lock);
    408391                        thread_ready(THREAD);
    409392                        break;
    410                
     393
    411394                case Exiting:
    412395repeat:
    413396                        if (THREAD->detached) {
    414                                 thread_destroy(THREAD, false);
     397                                thread_destroy(THREAD);
    415398                        } else {
    416399                                /*
    417400                                 * The thread structure is kept allocated until
    418401                                 * somebody calls thread_detach() on it.
    419                                  *
    420402                                 */
    421                                 if (!irq_spinlock_trylock(&THREAD->join_wq.lock)) {
     403                                if (!spinlock_trylock(&THREAD->join_wq.lock)) {
    422404                                        /*
    423405                                         * Avoid deadlock.
    424                                          *
    425406                                         */
    426                                         irq_spinlock_unlock(&THREAD->lock, false);
     407                                        spinlock_unlock(&THREAD->lock);
    427408                                        delay(HZ);
    428                                         irq_spinlock_lock(&THREAD->lock, false);
     409                                        spinlock_lock(&THREAD->lock);
    429410                                        DEADLOCK_PROBE(p_joinwq,
    430411                                            DEADLOCK_THRESHOLD);
     
    433414                                _waitq_wakeup_unsafe(&THREAD->join_wq,
    434415                                    WAKEUP_FIRST);
    435                                 irq_spinlock_unlock(&THREAD->join_wq.lock, false);
     416                                spinlock_unlock(&THREAD->join_wq.lock);
    436417                               
    437418                                THREAD->state = Lingering;
    438                                 irq_spinlock_unlock(&THREAD->lock, false);
     419                                spinlock_unlock(&THREAD->lock);
    439420                        }
    440421                        break;
     
    443424                        /*
    444425                         * Prefer the thread after it's woken up.
    445                          *
    446426                         */
    447427                        THREAD->priority = -1;
    448                        
     428
    449429                        /*
    450430                         * We need to release wq->lock which we locked in
    451431                         * waitq_sleep(). Address of wq->lock is kept in
    452432                         * THREAD->sleep_queue.
    453                          *
    454433                         */
    455                         irq_spinlock_unlock(&THREAD->sleep_queue->lock, false);
    456                        
    457                         irq_spinlock_unlock(&THREAD->lock, false);
     434                        spinlock_unlock(&THREAD->sleep_queue->lock);
     435
     436                        /*
     437                         * Check for possible requests for out-of-context
     438                         * invocation.
     439                         */
     440                        if (THREAD->call_me) {
     441                                THREAD->call_me(THREAD->call_me_with);
     442                                THREAD->call_me = NULL;
     443                                THREAD->call_me_with = NULL;
     444                        }
     445
     446                        spinlock_unlock(&THREAD->lock);
     447
    458448                        break;
    459                
     449
    460450                default:
    461451                        /*
    462452                         * Entering state is unexpected.
    463                          *
    464453                         */
    465454                        panic("tid%" PRIu64 ": unexpected state %s.",
     
    467456                        break;
    468457                }
    469                
     458
    470459                THREAD = NULL;
    471460        }
    472        
     461
    473462        THREAD = find_best_thread();
    474463       
    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        
     464        spinlock_lock(&THREAD->lock);
     465        priority = THREAD->priority;
     466        spinlock_unlock(&THREAD->lock);
     467
     468        relink_rq(priority);           
     469
    481470        /*
    482471         * If both the old and the new task are the same, lots of work is
    483472         * avoided.
    484          *
    485473         */
    486474        if (TASK != THREAD->task) {
    487                 as_t *new_as = THREAD->task->as;
     475                as_t *as1 = NULL;
     476                as_t *as2;
     477
     478                if (TASK) {
     479                        spinlock_lock(&TASK->lock);
     480                        as1 = TASK->as;
     481                        spinlock_unlock(&TASK->lock);
     482                }
     483
     484                spinlock_lock(&THREAD->task->lock);
     485                as2 = THREAD->task->as;
     486                spinlock_unlock(&THREAD->task->lock);
    488487               
    489488                /*
    490489                 * Note that it is possible for two tasks to share one address
    491490                 * space.
    492                  (
    493491                 */
    494                 if (old_as != new_as) {
     492                if (as1 != as2) {
    495493                        /*
    496494                         * Both tasks and address spaces are different.
    497495                         * Replace the old one with the new one.
    498                          *
    499496                         */
    500                         as_switch(old_as, new_as);
    501                 }
    502                
     497                        as_switch(as1, as2);
     498                }
    503499                TASK = THREAD->task;
    504500                before_task_runs();
    505501        }
    506        
    507         if (old_task)
    508                 task_release(old_task);
    509        
    510         if (old_as)
    511                 as_release(old_as);
    512        
    513         irq_spinlock_lock(&THREAD->lock, false);
     502
     503        spinlock_lock(&THREAD->lock);   
    514504        THREAD->state = Running;
    515        
     505
    516506#ifdef SCHEDULER_VERBOSE
    517507        printf("cpu%u: tid %" PRIu64 " (priority=%d, ticks=%" PRIu64
    518508            ", nrdy=%ld)\n", CPU->id, THREAD->tid, THREAD->priority,
    519509            THREAD->ticks, atomic_get(&CPU->nrdy));
    520 #endif
    521        
     510#endif 
     511
    522512        /*
    523513         * Some architectures provide late kernel PA2KA(identity)
     
    527517         * necessary, is to be mapped in before_thread_runs(). This
    528518         * function must be executed before the switch to the new stack.
    529          *
    530519         */
    531520        before_thread_runs();
    532        
     521
    533522        /*
    534523         * Copy the knowledge of CPU, TASK, THREAD and preemption counter to
    535524         * thread's stack.
    536          *
    537525         */
    538526        the_copy(THE, (the_t *) THREAD->kstack);
    539527       
    540528        context_restore(&THREAD->saved_context);
    541        
    542         /* Not reached */
     529        /* not reached */
    543530}
    544531
     
    554541void kcpulb(void *arg)
    555542{
    556         atomic_count_t average;
    557         atomic_count_t rdy;
    558        
     543        thread_t *t;
     544        int count, average, j, k = 0;
     545        unsigned int i;
     546        ipl_t ipl;
     547
    559548        /*
    560549         * Detach kcpulb as nobody will call thread_join_timeout() on it.
     
    567556         */
    568557        thread_sleep(1);
    569        
     558
    570559not_satisfied:
    571560        /*
     
    573562         * other CPU's. Note that situation can have changed between two
    574563         * passes. Each time get the most up to date counts.
    575          *
    576564         */
    577565        average = atomic_get(&nrdy) / config.cpu_active + 1;
    578         rdy = atomic_get(&CPU->nrdy);
    579        
    580         if (average <= rdy)
     566        count = average - atomic_get(&CPU->nrdy);
     567
     568        if (count <= 0)
    581569                goto satisfied;
    582        
    583         atomic_count_t count = average - rdy;
    584        
     570
    585571        /*
    586572         * Searching least priority queues on all CPU's first and most priority
    587573         * 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                        
     574         */
     575        for (j = RQ_COUNT - 1; j >= 0; j--) {
     576                for (i = 0; i < config.cpu_active; i++) {
     577                        link_t *l;
     578                        runq_t *r;
     579                        cpu_t *cpu;
     580
     581                        cpu = &cpus[(i + k) % config.cpu_active];
     582
    598583                        /*
    599584                         * Not interested in ourselves.
    600585                         * Doesn't require interrupt disabling for kcpulb has
    601586                         * THREAD_FLAG_WIRED.
    602                          *
    603587                         */
    604588                        if (CPU == cpu)
    605589                                continue;
    606                        
    607590                        if (atomic_get(&cpu->nrdy) <= average)
    608591                                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);
     592
     593                        ipl = interrupts_disable();
     594                        r = &cpu->rq[j];
     595                        spinlock_lock(&r->lock);
     596                        if (r->n == 0) {
     597                                spinlock_unlock(&r->lock);
     598                                interrupts_restore(ipl);
    613599                                continue;
    614600                        }
    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                                
     601               
     602                        t = NULL;
     603                        l = r->rq_head.prev;    /* search rq from the back */
     604                        while (l != &r->rq_head) {
     605                                t = list_get_instance(l, thread_t, rq_link);
    624606                                /*
    625607                                 * We don't want to steal CPU-wired threads
     
    629611                                 * steal threads whose FPU context is still in
    630612                                 * CPU.
    631                                  *
    632613                                 */
    633                                 irq_spinlock_lock(&thread->lock, false);
    634                                
    635                                 if ((!(thread->flags & (THREAD_FLAG_WIRED | THREAD_FLAG_STOLEN)))
    636                                     && (!(thread->fpu_context_engaged))) {
     614                                spinlock_lock(&t->lock);
     615                                if ((!(t->flags & (THREAD_FLAG_WIRED |
     616                                    THREAD_FLAG_STOLEN))) &&
     617                                    (!(t->fpu_context_engaged))) {
    637618                                        /*
    638                                          * Remove thread from ready queue.
     619                                         * Remove t from r.
    639620                                         */
    640                                         irq_spinlock_unlock(&thread->lock, false);
     621                                        spinlock_unlock(&t->lock);
    641622                                       
    642623                                        atomic_dec(&cpu->nrdy);
    643624                                        atomic_dec(&nrdy);
    644                                        
    645                                         cpu->rq[rq].n--;
    646                                         list_remove(&thread->rq_link);
    647                                        
     625
     626                                        r->n--;
     627                                        list_remove(&t->rq_link);
     628
    648629                                        break;
    649630                                }
    650                                
    651                                 irq_spinlock_unlock(&thread->lock, false);
    652                                
    653                                 link = link->prev;
    654                                 thread = NULL;
     631                                spinlock_unlock(&t->lock);
     632                                l = l->prev;
     633                                t = NULL;
    655634                        }
    656                        
    657                         if (thread) {
     635                        spinlock_unlock(&r->lock);
     636
     637                        if (t) {
    658638                                /*
    659                                  * Ready thread on local CPU
    660                                  *
     639                                 * Ready t on local CPU
    661640                                 */
    662                                
    663                                 irq_spinlock_pass(&(cpu->rq[rq].lock), &thread->lock);
    664                                
     641                                spinlock_lock(&t->lock);
    665642#ifdef KCPULB_VERBOSE
    666643                                printf("kcpulb%u: TID %" PRIu64 " -> cpu%u, "
     
    669646                                    atomic_get(&nrdy) / config.cpu_active);
    670647#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                                
     648                                t->flags |= THREAD_FLAG_STOLEN;
     649                                t->state = Entering;
     650                                spinlock_unlock(&t->lock);
     651       
     652                                thread_ready(t);
     653
     654                                interrupts_restore(ipl);
     655       
    678656                                if (--count == 0)
    679657                                        goto satisfied;
    680                                
     658                                       
    681659                                /*
    682660                                 * We are not satisfied yet, focus on another
    683661                                 * CPU next time.
    684                                  *
    685662                                 */
    686                                 acpu_bias++;
     663                                k++;
    687664                               
    688665                                continue;
    689                         } else
    690                                 irq_spinlock_unlock(&(cpu->rq[rq].lock), true);
    691                        
    692                 }
    693         }
    694        
     666                        }
     667                        interrupts_restore(ipl);
     668                }
     669        }
     670
    695671        if (atomic_get(&CPU->nrdy)) {
    696672                /*
    697673                 * Be a little bit light-weight and let migrated threads run.
    698                  *
    699674                 */
    700675                scheduler();
     
    703678                 * We failed to migrate a single thread.
    704679                 * Give up this turn.
    705                  *
    706680                 */
    707681                goto loop;
    708682        }
    709        
     683               
    710684        goto not_satisfied;
    711        
     685
    712686satisfied:
    713687        goto loop;
    714688}
     689
    715690#endif /* CONFIG_SMP */
    716691
    717 /** Print information about threads & scheduler queues
    718  *
    719  */
     692
     693/** Print information about threads & scheduler queues */
    720694void sched_print_list(void)
    721695{
    722         size_t cpu;
     696        ipl_t ipl;
     697        unsigned int cpu, i;
     698        runq_t *r;
     699        thread_t *t;
     700        link_t *cur;
     701
     702        /* We are going to mess with scheduler structures,
     703         * let's not be interrupted */
     704        ipl = interrupts_disable();
    723705        for (cpu = 0; cpu < config.cpu_count; cpu++) {
     706
    724707                if (!cpus[cpu].active)
    725708                        continue;
    726                
    727                 irq_spinlock_lock(&cpus[cpu].lock, true);
    728                
    729                 printf("cpu%u: address=%p, nrdy=%" PRIua ", needs_relink=%zu\n",
     709
     710                spinlock_lock(&cpus[cpu].lock);
     711                printf("cpu%u: address=%p, nrdy=%ld, needs_relink=%" PRIs "\n",
    730712                    cpus[cpu].id, &cpus[cpu], atomic_get(&cpus[cpu].nrdy),
    731713                    cpus[cpu].needs_relink);
    732714               
    733                 unsigned int i;
    734715                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);
     716                        r = &cpus[cpu].rq[i];
     717                        spinlock_lock(&r->lock);
     718                        if (!r->n) {
     719                                spinlock_unlock(&r->lock);
    738720                                continue;
    739721                        }
    740                        
    741722                        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]);
     723                        for (cur = r->rq_head.next; cur != &r->rq_head;
     724                                cur = cur->next) {
     725                                t = list_get_instance(cur, thread_t, rq_link);
     726                                printf("%" PRIu64 "(%s) ", t->tid,
     727                                    thread_states[t->state]);
    749728                        }
    750729                        printf("\n");
    751                        
    752                         irq_spinlock_unlock(&(cpus[cpu].rq[i].lock), false);
    753                 }
    754                
    755                 irq_spinlock_unlock(&cpus[cpu].lock, true);
    756         }
     730                        spinlock_unlock(&r->lock);
     731                }
     732                spinlock_unlock(&cpus[cpu].lock);
     733        }
     734       
     735        interrupts_restore(ipl);
    757736}
    758737
Note: See TracChangeset for help on using the changeset viewer.