Rev 779 | Rev 784 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 779 | Rev 783 | ||
|---|---|---|---|
| Line 117... | Line 117... | ||
| 117 | */ |
117 | */ |
| 118 | static thread_t *find_best_thread(void) |
118 | static thread_t *find_best_thread(void) |
| 119 | { |
119 | { |
| 120 | thread_t *t; |
120 | thread_t *t; |
| 121 | runq_t *r; |
121 | runq_t *r; |
| 122 | int i, n; |
122 | int i; |
| 123 | 123 | ||
| 124 | ASSERT(CPU != NULL); |
124 | ASSERT(CPU != NULL); |
| 125 | 125 | ||
| 126 | loop: |
126 | loop: |
| 127 | interrupts_disable(); |
- | |
| 128 | - | ||
| 129 | spinlock_lock(&CPU->lock); |
- | |
| 130 | n = CPU->nrdy; |
- | |
| 131 | spinlock_unlock(&CPU->lock); |
- | |
| 132 | - | ||
| 133 | interrupts_enable(); |
127 | interrupts_enable(); |
| 134 | 128 | ||
| 135 | if (n == 0) { |
129 | if (atomic_get(&CPU->nrdy) == 0) { |
| 136 | /* |
130 | /* |
| 137 | * For there was nothing to run, the CPU goes to sleep |
131 | * For there was nothing to run, the CPU goes to sleep |
| 138 | * until a hardware interrupt or an IPI comes. |
132 | * until a hardware interrupt or an IPI comes. |
| 139 | * This improves energy saving and hyperthreading. |
133 | * This improves energy saving and hyperthreading. |
| 140 | */ |
134 | */ |
| Line 143... | Line 137... | ||
| 143 | } |
137 | } |
| 144 | 138 | ||
| 145 | interrupts_disable(); |
139 | interrupts_disable(); |
| 146 | 140 | ||
| 147 | i = 0; |
141 | i = 0; |
| 148 | retry: |
- | |
| 149 | for (; i<RQ_COUNT; i++) { |
142 | for (; i<RQ_COUNT; i++) { |
| 150 | r = &CPU->rq[i]; |
143 | r = &CPU->rq[i]; |
| 151 | spinlock_lock(&r->lock); |
144 | spinlock_lock(&r->lock); |
| 152 | if (r->n == 0) { |
145 | if (r->n == 0) { |
| 153 | /* |
146 | /* |
| Line 155... | Line 148... | ||
| 155 | */ |
148 | */ |
| 156 | spinlock_unlock(&r->lock); |
149 | spinlock_unlock(&r->lock); |
| 157 | continue; |
150 | continue; |
| 158 | } |
151 | } |
| 159 | 152 | ||
| 160 | /* avoid deadlock with relink_rq() */ |
- | |
| 161 | if (!spinlock_trylock(&CPU->lock)) { |
- | |
| 162 | /* |
- | |
| 163 | * Unlock r and try again. |
- | |
| 164 | */ |
- | |
| 165 | spinlock_unlock(&r->lock); |
- | |
| 166 | goto retry; |
- | |
| 167 | } |
- | |
| 168 | CPU->nrdy--; |
- | |
| 169 | spinlock_unlock(&CPU->lock); |
153 | atomic_dec(&CPU->nrdy); |
| 170 | - | ||
| 171 | atomic_dec(&nrdy); |
154 | atomic_dec(&nrdy); |
| 172 | r->n--; |
155 | r->n--; |
| 173 | 156 | ||
| 174 | /* |
157 | /* |
| 175 | * Take the first thread from the queue. |
158 | * Take the first thread from the queue. |
| Line 462... | Line 445... | ||
| 462 | * |
445 | * |
| 463 | */ |
446 | */ |
| 464 | void kcpulb(void *arg) |
447 | void kcpulb(void *arg) |
| 465 | { |
448 | { |
| 466 | thread_t *t; |
449 | thread_t *t; |
| 467 | int count, i, j, k = 0; |
450 | int count, average, i, j, k = 0; |
| 468 | ipl_t ipl; |
451 | ipl_t ipl; |
| 469 | 452 | ||
| 470 | loop: |
453 | loop: |
| 471 | /* |
454 | /* |
| 472 | * Work in 1s intervals. |
455 | * Work in 1s intervals. |
| Line 477... | Line 460... | ||
| 477 | /* |
460 | /* |
| 478 | * Calculate the number of threads that will be migrated/stolen from |
461 | * Calculate the number of threads that will be migrated/stolen from |
| 479 | * other CPU's. Note that situation can have changed between two |
462 | * other CPU's. Note that situation can have changed between two |
| 480 | * passes. Each time get the most up to date counts. |
463 | * passes. Each time get the most up to date counts. |
| 481 | */ |
464 | */ |
| 482 | ipl = interrupts_disable(); |
- | |
| 483 | spinlock_lock(&CPU->lock); |
- | |
| 484 | count = atomic_get(&nrdy) / config.cpu_active; |
465 | average = atomic_get(&nrdy) / config.cpu_active; |
| 485 | count -= CPU->nrdy; |
466 | count = average - atomic_get(&CPU->nrdy); |
| 486 | spinlock_unlock(&CPU->lock); |
- | |
| 487 | interrupts_restore(ipl); |
- | |
| 488 | 467 | ||
| 489 | if (count <= 0) |
468 | if (count < 0) |
| 490 | goto satisfied; |
469 | goto satisfied; |
| 491 | 470 | ||
| - | 471 | if (!count) { /* Try to steal threads from CPU's that have more then average count */ |
|
| - | 472 | count = 1; |
|
| - | 473 | average += 1; |
|
| - | 474 | } |
|
| - | 475 | ||
| 492 | /* |
476 | /* |
| 493 | * Searching least priority queues on all CPU's first and most priority queues on all CPU's last. |
477 | * Searching least priority queues on all CPU's first and most priority queues on all CPU's last. |
| 494 | */ |
478 | */ |
| 495 | for (j=RQ_COUNT-1; j >= 0; j--) { |
479 | for (j=RQ_COUNT-1; j >= 0; j--) { |
| 496 | for (i=0; i < config.cpu_active; i++) { |
480 | for (i=0; i < config.cpu_active; i++) { |
| Line 503... | Line 487... | ||
| 503 | /* |
487 | /* |
| 504 | * Not interested in ourselves. |
488 | * Not interested in ourselves. |
| 505 | * Doesn't require interrupt disabling for kcpulb is X_WIRED. |
489 | * Doesn't require interrupt disabling for kcpulb is X_WIRED. |
| 506 | */ |
490 | */ |
| 507 | if (CPU == cpu) |
491 | if (CPU == cpu) |
| - | 492 | continue; |
|
| - | 493 | if (atomic_get(&cpu->nrdy) <= average) |
|
| 508 | continue; |
494 | continue; |
| 509 | 495 | ||
| 510 | restart: ipl = interrupts_disable(); |
496 | restart: ipl = interrupts_disable(); |
| 511 | r = &cpu->rq[j]; |
497 | r = &cpu->rq[j]; |
| 512 | spinlock_lock(&r->lock); |
498 | spinlock_lock(&r->lock); |
| 513 | if (r->n == 0) { |
499 | if (r->n == 0) { |
| Line 542... | Line 528... | ||
| 542 | /* Release all locks and try again. */ |
528 | /* Release all locks and try again. */ |
| 543 | spinlock_unlock(&r->lock); |
529 | spinlock_unlock(&r->lock); |
| 544 | interrupts_restore(ipl); |
530 | interrupts_restore(ipl); |
| 545 | goto restart; |
531 | goto restart; |
| 546 | } |
532 | } |
| 547 | cpu->nrdy--; |
533 | atomic_dec(&cpu->nrdy); |
| 548 | spinlock_unlock(&cpu->lock); |
534 | spinlock_unlock(&cpu->lock); |
| 549 | 535 | ||
| 550 | atomic_dec(&nrdy); |
536 | atomic_dec(&nrdy); |
| 551 | 537 | ||
| 552 | r->n--; |
538 | r->n--; |
| Line 564... | Line 550... | ||
| 564 | /* |
550 | /* |
| 565 | * Ready t on local CPU |
551 | * Ready t on local CPU |
| 566 | */ |
552 | */ |
| 567 | spinlock_lock(&t->lock); |
553 | spinlock_lock(&t->lock); |
| 568 | #ifdef KCPULB_VERBOSE |
554 | #ifdef KCPULB_VERBOSE |
| 569 | printf("kcpulb%d: TID %d -> cpu%d, nrdy=%d, avg=%d\n", CPU->id, t->tid, CPU->id, CPU->nrdy, atomic_get(&nrdy) / config.cpu_active); |
555 | printf("kcpulb%d: TID %d -> cpu%d, nrdy=%d, avg=%d\n", CPU->id, t->tid, CPU->id, atomic_get(&CPU->nrdy), atomic_get(&nrdy) / config.cpu_active); |
| 570 | #endif |
556 | #endif |
| 571 | t->flags |= X_STOLEN; |
557 | t->flags |= X_STOLEN; |
| 572 | spinlock_unlock(&t->lock); |
558 | spinlock_unlock(&t->lock); |
| 573 | 559 | ||
| 574 | thread_ready(t); |
560 | thread_ready(t); |
| Line 587... | Line 573... | ||
| 587 | } |
573 | } |
| 588 | interrupts_restore(ipl); |
574 | interrupts_restore(ipl); |
| 589 | } |
575 | } |
| 590 | } |
576 | } |
| 591 | 577 | ||
| 592 | if (CPU->nrdy) { |
578 | if (atomic_get(&CPU->nrdy)) { |
| 593 | /* |
579 | /* |
| 594 | * Be a little bit light-weight and let migrated threads run. |
580 | * Be a little bit light-weight and let migrated threads run. |
| 595 | */ |
581 | */ |
| 596 | scheduler(); |
582 | scheduler(); |
| 597 | } else { |
583 | } else { |
| Line 627... | Line 613... | ||
| 627 | for (cpu=0;cpu < config.cpu_count; cpu++) { |
613 | for (cpu=0;cpu < config.cpu_count; cpu++) { |
| 628 | if (!cpus[cpu].active) |
614 | if (!cpus[cpu].active) |
| 629 | continue; |
615 | continue; |
| 630 | spinlock_lock(&cpus[cpu].lock); |
616 | spinlock_lock(&cpus[cpu].lock); |
| 631 | printf("cpu%d: nrdy: %d needs_relink: %d\n", |
617 | printf("cpu%d: nrdy: %d needs_relink: %d\n", |
| 632 | cpus[cpu].id, cpus[cpu].nrdy, cpus[cpu].needs_relink); |
618 | cpus[cpu].id, atomic_get(&cpus[cpu].nrdy), cpus[cpu].needs_relink); |
| 633 | 619 | ||
| 634 | for (i=0; i<RQ_COUNT; i++) { |
620 | for (i=0; i<RQ_COUNT; i++) { |
| 635 | r = &cpus[cpu].rq[i]; |
621 | r = &cpus[cpu].rq[i]; |
| 636 | spinlock_lock(&r->lock); |
622 | spinlock_lock(&r->lock); |
| 637 | if (!r->n) { |
623 | if (!r->n) { |