Rev 2292 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2292 | Rev 2307 | ||
---|---|---|---|
Line 59... | Line 59... | ||
59 | #include <adt/list.h> |
59 | #include <adt/list.h> |
60 | #include <panic.h> |
60 | #include <panic.h> |
61 | #include <cpu.h> |
61 | #include <cpu.h> |
62 | #include <print.h> |
62 | #include <print.h> |
63 | #include <debug.h> |
63 | #include <debug.h> |
- | 64 | #include <synch/rcu.h> |
|
64 | 65 | ||
65 | static void before_task_runs(void); |
66 | static void before_task_runs(void); |
66 | static void before_thread_runs(void); |
67 | static void before_thread_runs(void); |
67 | static void after_thread_ran(void); |
68 | static void after_thread_ran(void); |
68 | static void scheduler_separated_stack(void); |
69 | static void scheduler_separated_stack(void); |
Line 113... | Line 114... | ||
113 | * |
114 | * |
114 | */ |
115 | */ |
115 | void after_thread_ran(void) |
116 | void after_thread_ran(void) |
116 | { |
117 | { |
117 | after_thread_ran_arch(); |
118 | after_thread_ran_arch(); |
- | 119 | rcu_run_callbacks(); |
|
118 | } |
120 | } |
119 | 121 | ||
120 | #ifdef CONFIG_FPU_LAZY |
122 | #ifdef CONFIG_FPU_LAZY |
121 | void scheduler_fpu_lazy_request(void) |
123 | void scheduler_fpu_lazy_request(void) |
122 | { |
124 | { |
Line 205... | Line 207... | ||
205 | goto loop; |
207 | goto loop; |
206 | } |
208 | } |
207 | 209 | ||
208 | interrupts_disable(); |
210 | interrupts_disable(); |
209 | 211 | ||
210 | for (i = 0; i<RQ_COUNT; i++) { |
212 | for (i = 0; i < RQ_COUNT; i++) { |
211 | r = &CPU->rq[i]; |
213 | r = &CPU->rq[i]; |
212 | spinlock_lock(&r->lock); |
214 | spinlock_lock(&r->lock); |
213 | if (r->n == 0) { |
215 | if (r->n == 0) { |
214 | /* |
216 | /* |
215 | * If this queue is empty, try a lower-priority queue. |
217 | * If this queue is empty, try a lower-priority queue. |
Line 375... | Line 377... | ||
375 | * Assume THREAD->lock is held. |
377 | * Assume THREAD->lock is held. |
376 | */ |
378 | */ |
377 | void scheduler_separated_stack(void) |
379 | void scheduler_separated_stack(void) |
378 | { |
380 | { |
379 | int priority; |
381 | int priority; |
- | 382 | DEADLOCK_PROBE_INIT(p_joinwq); |
|
380 | 383 | ||
381 | ASSERT(CPU != NULL); |
384 | ASSERT(CPU != NULL); |
382 | 385 | ||
383 | if (THREAD) { |
386 | if (THREAD) { |
384 | /* must be run after the switch to scheduler stack */ |
387 | /* must be run after the switch to scheduler stack */ |
385 | after_thread_ran(); |
388 | after_thread_ran(); |
Line 404... | Line 407... | ||
404 | * Avoid deadlock. |
407 | * Avoid deadlock. |
405 | */ |
408 | */ |
406 | spinlock_unlock(&THREAD->lock); |
409 | spinlock_unlock(&THREAD->lock); |
407 | delay(10); |
410 | delay(10); |
408 | spinlock_lock(&THREAD->lock); |
411 | spinlock_lock(&THREAD->lock); |
- | 412 | DEADLOCK_PROBE(p_joinwq, |
|
- | 413 | DEADLOCK_THRESHOLD); |
|
409 | goto repeat; |
414 | goto repeat; |
410 | } |
415 | } |
411 | _waitq_wakeup_unsafe(&THREAD->join_wq, false); |
416 | _waitq_wakeup_unsafe(&THREAD->join_wq, false); |
412 | spinlock_unlock(&THREAD->join_wq.lock); |
417 | spinlock_unlock(&THREAD->join_wq.lock); |
413 | 418 | ||
Line 445... | Line 450... | ||
445 | 450 | ||
446 | default: |
451 | default: |
447 | /* |
452 | /* |
448 | * Entering state is unexpected. |
453 | * Entering state is unexpected. |
449 | */ |
454 | */ |
450 | panic("tid%d: unexpected state %s\n", THREAD->tid, |
455 | panic("tid%llu: unexpected state %s\n", THREAD->tid, |
451 | thread_states[THREAD->state]); |
456 | thread_states[THREAD->state]); |
452 | break; |
457 | break; |
453 | } |
458 | } |
454 | 459 | ||
455 | THREAD = NULL; |
460 | THREAD = NULL; |
456 | } |
461 | } |
Line 498... | Line 503... | ||
498 | 503 | ||
499 | spinlock_lock(&THREAD->lock); |
504 | spinlock_lock(&THREAD->lock); |
500 | THREAD->state = Running; |
505 | THREAD->state = Running; |
501 | 506 | ||
502 | #ifdef SCHEDULER_VERBOSE |
507 | #ifdef SCHEDULER_VERBOSE |
503 | printf("cpu%d: tid %d (priority=%d, ticks=%lld, nrdy=%ld)\n", |
508 | printf("cpu%d: tid %llu (priority=%d, ticks=%llu, nrdy=%ld)\n", |
504 | CPU->id, THREAD->tid, THREAD->priority, THREAD->ticks, |
509 | CPU->id, THREAD->tid, THREAD->priority, THREAD->ticks, |
505 | atomic_get(&CPU->nrdy)); |
510 | atomic_get(&CPU->nrdy)); |
506 | #endif |
511 | #endif |
507 | 512 | ||
508 | /* |
513 | /* |
Line 566... | Line 571... | ||
566 | 571 | ||
567 | /* |
572 | /* |
568 | * Searching least priority queues on all CPU's first and most priority |
573 | * Searching least priority queues on all CPU's first and most priority |
569 | * queues on all CPU's last. |
574 | * queues on all CPU's last. |
570 | */ |
575 | */ |
571 | for (j= RQ_COUNT - 1; j >= 0; j--) { |
576 | for (j = RQ_COUNT - 1; j >= 0; j--) { |
572 | for (i = 0; i < config.cpu_active; i++) { |
577 | for (i = 0; i < config.cpu_active; i++) { |
573 | link_t *l; |
578 | link_t *l; |
574 | runq_t *r; |
579 | runq_t *r; |
575 | cpu_t *cpu; |
580 | cpu_t *cpu; |
576 | 581 | ||
Line 607... | Line 612... | ||
607 | * steal threads whose FPU context is still in |
612 | * steal threads whose FPU context is still in |
608 | * CPU. |
613 | * CPU. |
609 | */ |
614 | */ |
610 | spinlock_lock(&t->lock); |
615 | spinlock_lock(&t->lock); |
611 | if ((!(t->flags & (THREAD_FLAG_WIRED | |
616 | if ((!(t->flags & (THREAD_FLAG_WIRED | |
612 | THREAD_FLAG_STOLEN))) && |
617 | THREAD_FLAG_STOLEN))) && |
613 | (!(t->fpu_context_engaged)) ) { |
618 | (!(t->fpu_context_engaged))) { |
614 | /* |
619 | /* |
615 | * Remove t from r. |
620 | * Remove t from r. |
616 | */ |
621 | */ |
617 | spinlock_unlock(&t->lock); |
622 | spinlock_unlock(&t->lock); |
618 | 623 | ||
Line 634... | Line 639... | ||
634 | /* |
639 | /* |
635 | * Ready t on local CPU |
640 | * Ready t on local CPU |
636 | */ |
641 | */ |
637 | spinlock_lock(&t->lock); |
642 | spinlock_lock(&t->lock); |
638 | #ifdef KCPULB_VERBOSE |
643 | #ifdef KCPULB_VERBOSE |
639 | printf("kcpulb%d: TID %d -> cpu%d, nrdy=%ld, " |
644 | printf("kcpulb%d: TID %llu -> cpu%d, nrdy=%ld, " |
640 | "avg=%nd\n", CPU->id, t->tid, CPU->id, |
645 | "avg=%nd\n", CPU->id, t->tid, CPU->id, |
641 | atomic_get(&CPU->nrdy), |
646 | atomic_get(&CPU->nrdy), |
642 | atomic_get(&nrdy) / config.cpu_active); |
647 | atomic_get(&nrdy) / config.cpu_active); |
643 | #endif |
648 | #endif |
644 | t->flags |= THREAD_FLAG_STOLEN; |
649 | t->flags |= THREAD_FLAG_STOLEN; |
Line 717... | Line 722... | ||
717 | } |
722 | } |
718 | printf("\trq[%d]: ", i); |
723 | printf("\trq[%d]: ", i); |
719 | for (cur = r->rq_head.next; cur != &r->rq_head; |
724 | for (cur = r->rq_head.next; cur != &r->rq_head; |
720 | cur = cur->next) { |
725 | cur = cur->next) { |
721 | t = list_get_instance(cur, thread_t, rq_link); |
726 | t = list_get_instance(cur, thread_t, rq_link); |
722 | printf("%d(%s) ", t->tid, |
727 | printf("%llu(%s) ", t->tid, |
723 | thread_states[t->state]); |
728 | thread_states[t->state]); |
724 | } |
729 | } |
725 | printf("\n"); |
730 | printf("\n"); |
726 | spinlock_unlock(&r->lock); |
731 | spinlock_unlock(&r->lock); |
727 | } |
732 | } |