Add configUSE_SCHEDULER_CORE_MASK and vTaskSetSchedulerCoreMask API#1418
Open
kuopinghsu wants to merge 4 commits into
Open
Add configUSE_SCHEDULER_CORE_MASK and vTaskSetSchedulerCoreMask API#1418kuopinghsu wants to merge 4 commits into
kuopinghsu wants to merge 4 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
Adds an SMP-only “scheduler core mask” feature that lets applications dynamically restrict which cores may run non-idle tasks at runtime (e.g., for load/power management) via a new config gate and two new task APIs.
Changes:
- Introduces
configUSE_SCHEDULER_CORE_MASK(intended to gate the feature at compile time). - Adds
vTaskSetSchedulerCoreMask()/uxTaskGetSchedulerCoreMask()APIs and integrates the mask into SMP task selection to prevent scheduling non-idle tasks on disabled cores. - Updates the template configuration to expose the new option.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
tasks.c |
Adds a global scheduler core mask, enforces it in SMP scheduling paths, and implements the new APIs. |
include/task.h |
Declares and documents the new APIs under an SMP-only config guard. |
include/FreeRTOS.h |
Adds the new config macro default and a single-core build-time sanity check. |
examples/template_configuration/FreeRTOSConfig.h |
Documents/enables the new config in the SMP section of the template. |
Comments suppressed due to low confidence (1)
tasks.c:3144
vTaskSetSchedulerCoreMaskclamps with( 1UL << configNUMBER_OF_CORES ) - 1UL, which has the same undefined-shift risk as the static initializer and also ties the width tounsigned longrather thanUBaseType_t. Consider adding a width guard (similar to the existingUBaseType_tvsconfigNUMBER_OF_CORESassert used for core affinity) and computing the mask in a way that avoids undefined shifts.
uxOldMask = uxSchedulerCoreMask;
/* Clamp to the number of physical cores so stray bits are ignored. */
uxSchedulerCoreMask = uxCoreMask & ( UBaseType_t ) ( ( 1UL << configNUMBER_OF_CORES ) - 1UL );
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Add configUSE_SCHEDULER_CORE_MASK and vTaskSetSchedulerCoreMask API
Description
Adds a new SMP-only feature that lets the application control which
cores the FreeRTOS scheduler is permitted to run non-idle tasks on, at run
time, without stopping the scheduler.
The primary use cases are:
Dynamic load management -- exclude one or more cores from scheduling
non-idle work so they can be idled or throttled without stopping the
scheduler on the remaining cores.
Core power-off preparation -- before powering off a secondary core
(cores 1..N-1), clear that core's bit in the scheduler mask so the
scheduler stops assigning new tasks to it. Once the core's current task
yields and the core is running only its idle task, the platform power
management layer can safely gate the clock or cut power to that core.
Core 0 must never be masked out because it owns the tick and the
scheduler entry point.
A new configuration macro
configUSE_SCHEDULER_CORE_MASKgates the entirefeature. Setting it to
0produces a clean preprocessor rollback to theoriginal code with zero overhead.
Files changed:
tasks.cinclude/task.hinclude/FreeRTOS.hexamples/template_configuration/FreeRTOSConfig.hDetails:
include/FreeRTOS.h: added default#define configUSE_SCHEDULER_CORE_MASK 1and a compile-time
#errorthat blocks use on single-core builds.include/task.h: added declarations for both new API functions under thecombined
configNUMBER_OF_CORES > 1 && configUSE_SCHEDULER_CORE_MASK == 1guard.tasks.c: added theuxSchedulerCoreMaskstatic variable; added three#if ( configUSE_SCHEDULER_CORE_MASK == 1 )checks inside the SMP taskselection loop so that non-idle tasks are never assigned to or kept on a
masked core; added implementations of both API functions.
examples/template_configuration/FreeRTOSConfig.h: addedconfigUSE_SCHEDULER_CORE_MASK 1to the SMP section.Opt-out: set
#define configUSE_SCHEDULER_CORE_MASK 0inFreeRTOSConfig.h.Every added line is inside a preprocessor guard, so the build is identical
to the unpatched kernel.
New API (available when
configNUMBER_OF_CORES > 1andconfigUSE_SCHEDULER_CORE_MASK == 1):Usage example -- power off core 2 on a 4-core system:
Note: masking core 0 is valid at the scheduler level (core 0 will just run
only its idle task). What must not be done is powering off the core that
hosts the tick source (typically core 0), because the kernel tick and
scheduler entry point depend on it. Masking is a safe prerequisite step
before powering off any secondary core.
Test Steps
configNUMBER_OF_CORES > 1andconfigUSE_SCHEDULER_CORE_MASK 1(default). Confirm it compiles andlinks without warnings.
vTaskSetSchedulerCoreMask( 1U )at run time (only core 0 enabled).Confirm that tasks on cores 1..N-1 are no longer scheduled and those
cores run only their idle tasks.
vTaskSetSchedulerCoreMask( tskNO_AFFINITY ). Confirm normalscheduling resumes on all cores.
configUSE_SCHEDULER_CORE_MASK 0. Confirm it compilescleanly and that neither
vTaskSetSchedulerCoreMasknoruxTaskGetSchedulerCoreMaskis referenced in the output binary.configNUMBER_OF_CORES 1and any non-zero value ofconfigUSE_SCHEDULER_CORE_MASK. Confirm the expected#errorfires.Checklist:
Related Issue
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.