Rev 783 | Rev 785 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 783 | Rev 784 | ||
---|---|---|---|
Line 129... | Line 129... | ||
129 | if (atomic_get(&CPU->nrdy) == 0) { |
129 | if (atomic_get(&CPU->nrdy) == 0) { |
130 | /* |
130 | /* |
131 | * For there was nothing to run, the CPU goes to sleep |
131 | * For there was nothing to run, the CPU goes to sleep |
132 | * until a hardware interrupt or an IPI comes. |
132 | * until a hardware interrupt or an IPI comes. |
133 | * This improves energy saving and hyperthreading. |
133 | * This improves energy saving and hyperthreading. |
- | 134 | * |
|
- | 135 | * - we might get an interrupt here that makes some thread runnable, |
|
- | 136 | * in such a case we must wait for the next quantum to come |
|
134 | */ |
137 | */ |
135 | cpu_sleep(); |
138 | cpu_sleep(); |
136 | goto loop; |
139 | goto loop; |
137 | } |
140 | } |
138 | 141 | ||
Line 217... | Line 220... | ||
217 | r->n += n; |
220 | r->n += n; |
218 | spinlock_unlock(&r->lock); |
221 | spinlock_unlock(&r->lock); |
219 | } |
222 | } |
220 | CPU->needs_relink = 0; |
223 | CPU->needs_relink = 0; |
221 | } |
224 | } |
222 | spinlock_unlock(&CPU->lock); |
225 | spinlock_unlock(&CPU->lock); |
223 | 226 | ||
224 | } |
227 | } |
225 | 228 | ||
226 | 229 | ||
227 | /** Scheduler stack switch wrapper |
230 | /** Scheduler stack switch wrapper |
Line 460... | Line 463... | ||
460 | /* |
463 | /* |
461 | * Calculate the number of threads that will be migrated/stolen from |
464 | * Calculate the number of threads that will be migrated/stolen from |
462 | * other CPU's. Note that situation can have changed between two |
465 | * other CPU's. Note that situation can have changed between two |
463 | * passes. Each time get the most up to date counts. |
466 | * passes. Each time get the most up to date counts. |
464 | */ |
467 | */ |
465 | average = atomic_get(&nrdy) / config.cpu_active; |
468 | average = atomic_get(&nrdy) / config.cpu_active + 1; |
466 | count = average - atomic_get(&CPU->nrdy); |
469 | count = average - atomic_get(&CPU->nrdy); |
467 | 470 | ||
468 | if (count < 0) |
471 | if (count <= 0) |
469 | goto satisfied; |
472 | goto satisfied; |
470 | 473 | ||
471 | if (!count) { /* Try to steal threads from CPU's that have more then average count */ |
- | |
472 | count = 1; |
- | |
473 | average += 1; |
- | |
474 | } |
- | |
475 | - | ||
476 | /* |
474 | /* |
477 | * Searching least priority queues on all CPU's first and most priority queues on all CPU's last. |
475 | * Searching least priority queues on all CPU's first and most priority queues on all CPU's last. |
478 | */ |
476 | */ |
479 | for (j=RQ_COUNT-1; j >= 0; j--) { |
477 | for (j=RQ_COUNT-1; j >= 0; j--) { |
480 | for (i=0; i < config.cpu_active; i++) { |
478 | for (i=0; i < config.cpu_active; i++) { |
Line 491... | Line 489... | ||
491 | if (CPU == cpu) |
489 | if (CPU == cpu) |
492 | continue; |
490 | continue; |
493 | if (atomic_get(&cpu->nrdy) <= average) |
491 | if (atomic_get(&cpu->nrdy) <= average) |
494 | continue; |
492 | continue; |
495 | 493 | ||
496 | restart: ipl = interrupts_disable(); |
494 | ipl = interrupts_disable(); |
497 | r = &cpu->rq[j]; |
495 | r = &cpu->rq[j]; |
498 | spinlock_lock(&r->lock); |
496 | spinlock_lock(&r->lock); |
499 | if (r->n == 0) { |
497 | if (r->n == 0) { |
500 | spinlock_unlock(&r->lock); |
498 | spinlock_unlock(&r->lock); |
501 | interrupts_restore(ipl); |
499 | interrupts_restore(ipl); |
Line 511... | Line 509... | ||
511 | * The latter prevents threads from migrating between CPU's without ever being run. |
509 | * The latter prevents threads from migrating between CPU's without ever being run. |
512 | * We don't want to steal threads whose FPU context is still in CPU. |
510 | * We don't want to steal threads whose FPU context is still in CPU. |
513 | */ |
511 | */ |
514 | spinlock_lock(&t->lock); |
512 | spinlock_lock(&t->lock); |
515 | if ( (!(t->flags & (X_WIRED | X_STOLEN))) && (!(t->fpu_context_engaged)) ) { |
513 | if ( (!(t->flags & (X_WIRED | X_STOLEN))) && (!(t->fpu_context_engaged)) ) { |
516 | - | ||
517 | /* |
514 | /* |
518 | * Remove t from r. |
515 | * Remove t from r. |
519 | */ |
516 | */ |
520 | - | ||
521 | spinlock_unlock(&t->lock); |
517 | spinlock_unlock(&t->lock); |
522 | 518 | ||
523 | /* |
- | |
524 | * Here we have to avoid deadlock with relink_rq(), |
- | |
525 | * because it locks cpu and r in a different order than we do. |
- | |
526 | */ |
- | |
527 | if (!spinlock_trylock(&cpu->lock)) { |
- | |
528 | /* Release all locks and try again. */ |
- | |
529 | spinlock_unlock(&r->lock); |
- | |
530 | interrupts_restore(ipl); |
- | |
531 | goto restart; |
- | |
532 | } |
- | |
533 | atomic_dec(&cpu->nrdy); |
519 | atomic_dec(&cpu->nrdy); |
534 | spinlock_unlock(&cpu->lock); |
- | |
535 | - | ||
536 | atomic_dec(&nrdy); |
520 | atomic_dec(&nrdy); |
537 | 521 | ||
538 | r->n--; |
522 | r->n--; |
539 | list_remove(&t->rq_link); |
523 | list_remove(&t->rq_link); |
540 | 524 |