Draft: RFC: Enable granular locks for critical sections instead of a single kernel lock #601
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.
Enable granular locks for critical sections instead of a single kernel lock
Description
This commit updates all critical section APIs, viz.,
task*_CRITICAL()
, to accept a spinlock variable. These spinlocks are defined locally to each of the kernel data structures. This change moves away from the single kernel lock design therefore ensuring lesser contentions for critical section locks. This effectively increases the performance of the SMP kernel.The idea here is to have granularity in the critical section spinlocks. An example of how this improves performance is as below:
Current Design:
TaskA running on core#0 is in a critical section by calling a blocking function such as
uxTaskPriorityGet()
.TaskB running on core#1 is performing a queue operation by calling
xQueueGenericSend()
. TaskB will have to contest for the kernel lock in order to complete the queue operation. This would mean that TaskB will be blocked until TaskA releases the lock.Proposed Changes:
Under the new scheme with the above scenario, TaskB need not wait for TaskA to complete its operation as both the tasks will be contesting for separate locks which are local to the tasks module and the queue module respectively. This enables many kernel related operations to happen simultaneously across the cores, thereby helping in performance improvements in SMP systems.
Things to be considered
Currently the the
task*_CRITICAL()
macros are routed to thevTaskEnterCritical()
function which ensures atomicity but also has the scope of checking for state change of a task via the functionprvCheckForRunStateChange()
. Under the proposed design change, the task state change may need a rethink. It could be abstracted out to the port layer.Critical section nesting would need to be handled by the ports under the new design. This is currently handled by the kernel directly.
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.