diff --git a/include/kernel/thread.h b/include/kernel/thread.h index 8aa60e247..1d7baa4b1 100644 --- a/include/kernel/thread.h +++ b/include/kernel/thread.h @@ -191,7 +191,7 @@ static inline void updateRestartPC(tcb_t *tcb) void endTimeslice(bool_t can_timeout_fault); /* called when a thread has used up its head refill */ -void chargeBudget(ticks_t capacity, ticks_t consumed, bool_t canTimeoutFault); +void chargeBudget(ticks_t capacity, ticks_t consumed, bool_t canTimeoutFault, word_t core, bool_t isCurCPU); /* Update the kernels timestamp and stores in ksCurTime. * The difference between the previous kernel timestamp and the one just read @@ -236,7 +236,7 @@ static inline bool_t checkBudget(void) return true; } - chargeBudget(capacity, NODE_STATE(ksConsumed), true); + chargeBudget(capacity, NODE_STATE(ksConsumed), true, CURRENT_CPU_INDEX(), true); return false; } diff --git a/src/api/syscall.c b/src/api/syscall.c index 064416789..1b691d63d 100644 --- a/src/api/syscall.c +++ b/src/api/syscall.c @@ -533,7 +533,7 @@ static void handleYield(void) { #ifdef CONFIG_KERNEL_MCS /* Yield the current remaining budget */ - chargeBudget(0, REFILL_HEAD(NODE_STATE(ksCurSC)).rAmount, false); + chargeBudget(0, REFILL_HEAD(NODE_STATE(ksCurSC)).rAmount, false, CURRENT_CPU_INDEX(), true); #else tcbSchedDequeue(NODE_STATE(ksCurThread)); SCHED_APPEND_CURRENT_TCB; diff --git a/src/kernel/thread.c b/src/kernel/thread.c index 2c7b4e620..00f018d85 100644 --- a/src/kernel/thread.c +++ b/src/kernel/thread.c @@ -611,21 +611,21 @@ void setNextInterrupt(void) setDeadline(next_interrupt - getTimerPrecision()); } -void chargeBudget(ticks_t capacity, ticks_t consumed, bool_t canTimeoutFault) +void chargeBudget(ticks_t capacity, ticks_t consumed, bool_t canTimeoutFault, word_t core, bool_t isCurCPU) { - if (isRoundRobin(NODE_STATE(ksCurSC))) { - assert(refill_size(NODE_STATE(ksCurSC)) == MIN_REFILLS); - REFILL_HEAD(NODE_STATE(ksCurSC)).rAmount += REFILL_TAIL(NODE_STATE(ksCurSC)).rAmount; - REFILL_TAIL(NODE_STATE(ksCurSC)).rAmount = 0; + if (isRoundRobin(NODE_STATE_ON_CORE(ksCurSC, core))) { + assert(refill_size(NODE_STATE_ON_CORE(ksCurSC, core)) == MIN_REFILLS); + REFILL_HEAD(NODE_STATE_ON_CORE(ksCurSC, core)).rAmount += REFILL_TAIL(NODE_STATE_ON_CORE(ksCurSC, core)).rAmount; + REFILL_TAIL(NODE_STATE_ON_CORE(ksCurSC, core)).rAmount = 0; } else { - refill_budget_check(NODE_STATE(ksCurSC), consumed, capacity); + refill_budget_check(NODE_STATE_ON_CORE(ksCurSC, core), consumed, capacity); } - assert(REFILL_HEAD(NODE_STATE(ksCurSC)).rAmount >= MIN_BUDGET); - NODE_STATE(ksCurSC)->scConsumed += consumed; - NODE_STATE(ksConsumed) = 0; - if (likely(isRunnable(NODE_STATE(ksCurThread)))) { + assert(REFILL_HEAD(NODE_STATE_ON_CORE(ksCurSC, core)).rAmount >= MIN_BUDGET); + NODE_STATE_ON_CORE(ksCurSC, core)->scConsumed += consumed; + NODE_STATE_ON_CORE(ksConsumed, core) = 0; + if (isCurCPU && likely(isRunnable(NODE_STATE_ON_CORE(ksCurThread, core)))) { endTimeslice(canTimeoutFault); rescheduleRequired(); NODE_STATE(ksReprogram) = true; diff --git a/src/object/schedcontrol.c b/src/object/schedcontrol.c index b835c8063..f3e54ebbe 100644 --- a/src/object/schedcontrol.c +++ b/src/object/schedcontrol.c @@ -31,12 +31,21 @@ static exception_t invokeSchedControl_Configure(sched_context_t *target, word_t tcbSchedDequeue(target->scTcb); /* bill the current consumed amount before adjusting the params */ if (NODE_STATE_ON_CORE(ksCurSC, target->scCore) == target) { - ticks_t capacity = refill_capacity(target, NODE_STATE_ON_CORE(ksConsumed, target->scCore)); - if (checkBudget()) { - commitTime(); +#ifdef ENABLE_SMP_SUPPORT + if (target->scCore == getCurrentCPUIndex()) { +#endif /* ENABLE_SMP_SUPPORT */ + if (checkBudget()) { + commitTime(); + } +#ifdef ENABLE_SMP_SUPPORT } else { - chargeBudget(capacity, NODE_STATE_ON_CORE(ksConsumed, target->scCore), false); + /* if its a remote core, manually charge the budget */ + ticks_t capacity = refill_capacity(target, NODE_STATE_ON_CORE(ksConsumed, target->scCore)); + + chargeBudget(capacity, NODE_STATE_ON_CORE(ksConsumed, target->scCore), false, target->scCore, false); + doReschedule(target->scCore); } +#endif /* ENABLE_SMP_SUPPORT */ } }