Feature - SMP Granular Locks - #1154
Conversation
|
@chinglee-iot @aggarg This PR introduces the granular locks changes to the FreeRTOS kernel. Please have a look and we could have discussions/changes in this PR context. Thank you. cc: @ESP-Marius @Dazza0 |
|
Thank you for your contribution, I'll forward this request to the team. There are few error in the PR can you please try fixing them |
|
Hello @sudeep-mohanty, I am just following up if you had time to fix the build issues |
|
@rawalexe Yes! I shall work on the failures and would also do some refactoring for an easier review process. For now, I've put this PR in draft. |
0159a4a to
5bf8c33
Compare
|
Hi @sudeep-mohanty, |
5bf8c33 to
9f8acc7
Compare
Hi @ActoryOu, I've made some updates which should fix the CI failures however I could not understand why the link-verifier action fails. Seems more like a script failure to me. So this action would still fail. If you have more information on what is causing it, could you let me know and I shall fix it. Thanks. |
c79962d to
f50d476
Compare
|
Created a PR to fix the CI failure - FreeRTOS/FreeRTOS#1292 |
70eb466 to
edc1c98
Compare
|
chinglee-iot
left a comment
There was a problem hiding this comment.
Coding format and minor change suggestion.
5aede4a to
5860cfd
Compare
0bb306a to
cff470e
Compare
dd67c0a to
9decfa6
Compare
chinglee-iot
left a comment
There was a problem hiding this comment.
- Update const MISRA check
- Update to use STATIC to align with other module
- Update BASE_TYPE critical section logic
- Update for readability.
9decfa6 to
b218d11
Compare
…herit() xTaskPriorityInherit() is called inside a critical section from queue.c. This commit moves the critical section into xTaskPriorityInherit(). Co-authored-by: Sudeep Mohanty <sudeep.mohanty@espressif.com>
Changed xPreemptionDisable to be a count rather than a pdTRUE/pdFALSE. This allows nested calls to vTaskPreemptionEnable(), where a yield only occurs when xPreemptionDisable is 0. Co-authored-by: Sudeep Mohanty <sudeep.mohanty@espressif.com>
Adds the required checks for granular locking port macros.
Port Config:
- portUSING_GRANULAR_LOCKS to enable granular locks
- portCRITICAL_NESTING_IN_TCB should be disabled
Granular Locking Port Macros:
- Spinlocks
- portSPINLOCK_TYPE
- portINIT_SPINLOCK( pxSpinlock )
- portINIT_SPINLOCK_STATIC
- Locking
- portGET_SPINLOCK()
- portRELEASE_SPINLOCK()
Co-authored-by: Sudeep Mohanty <sudeep.mohanty@espressif.com>
- Updated prvCheckForRunStateChange() for granular locks
- Updated vTaskSuspendAll() and xTaskResumeAll()
- Now holds the xTaskSpinlock during kernel suspension
- Increments/decrements xPreemptionDisable. Only yields when 0, thus allowing
for nested suspensions across different data groups
Co-authored-by: Sudeep Mohanty <sudeep.mohanty@espressif.com>
Updated critical section macros with granular locks. Some tasks.c API relied on their callers to enter critical sections. This assumption no longer works under granular locking. Critical sections added to the following functions: - `vTaskInternalSetTimeOutState()` - `xTaskIncrementTick()` - `vTaskSwitchContext()` - `xTaskRemoveFromEventList()` - `vTaskInternalSetTimeOutState()` - `eTaskConfirmSleepModeStatus()` - `xTaskPriorityDisinherit()` - `pvTaskIncrementMutexHeldCount()` Added missing suspensions to the following functions: - `vTaskPlaceOnEventList()` - `vTaskPlaceOnUnorderedEventList()` - `vTaskPlaceOnEventListRestricted()` Fixed the locking in vTaskSwitchContext() vTaskSwitchContext() must aquire both kernel locks, viz., task lock and ISR lock. This is because, vTaskSwitchContext() can be called from either task context or ISR context. Also, vTaskSwitchContext() must not alter the interrupt state prematurely. Co-authored-by: Sudeep Mohanty <sudeep.mohanty@espressif.com>
Updated queue.c to use granular locking - Added xTaskSpinlock and xISRSpinlock - Replaced critical section macros with data group critical section macros such as taskENTER/EXIT_CRITICAL/_FROM_ISR() with queueENTER/EXIT_CRITICAL_FROM_ISR(). - Added vQueueEnterCritical/FromISR() and vQueueExitCritical/FromISR() which map to the data group critical section macros. - Added prvLockQueueForTasks() and prvUnlockQueueForTasks() as the granular locking equivalents to prvLockQueue() and prvUnlockQueue() respectively Co-authored-by: Sudeep Mohanty <sudeep.mohanty@espressif.com>
Updated event_groups.c to use granular locking - Added xTaskSpinlock and xISRSpinlock - Replaced critical section macros with data group critical section macros such as taskENTER/EXIT_CRITICAL/_FROM_ISR() with event_groupsENTER/EXIT_CRITICAL/_FROM_ISR(). - Added vEventGroupsEnterCritical/FromISR() and vEventGroupsExitCriti/FromISR() functions that map to the data group critical section macros. - Added prvLockEventGroupForTasks() and prvUnlockEventGroupForTasks() to suspend the event group when executing non-deterministic code. - xEventGroupSetBits() and vEventGroupDelete() accesses the kernel data group directly. Thus, added vTaskSuspendAll()/xTaskResumeAll() to these fucntions. Co-authored-by: Sudeep Mohanty <sudeep.mohanty@espressif.com>
Updated stream_buffer.c to use granular locking - Added xTaskSpinlock and xISRSpinlock - Replaced critical section macros with data group critical section macros such as taskENTER/EXIT_CRITICAL/_FROM_ISR() with sbENTER/EXIT_CRITICAL_FROM_ISR(). - Added vStreambuffersEnterCritical/FromISR() and vStreambuffersExitCritical/FromISR() to map to the data group critical section macros. - Added prvLockStreamBufferForTasks() and prvUnlockStreamBufferForTasks() to suspend the stream buffer when executing non-deterministic code. Co-authored-by: Sudeep Mohanty <sudeep.mohanty@espressif.com>
Updated timers.c to use granular locking - Added xTaskSpinlock and xISRSpinlock - Replaced critical section macros with data group critical section macros such as taskENTER/EXIT_CRITICAL() with tmrENTER/EXIT_CRITICAL(). - Added vTimerEnterCritical() and vTimerExitCritical() to map to the data group critical section macros. Co-authored-by: Sudeep Mohanty <sudeep.mohanty@espressif.com>
The design document captures the **Dual Spinlock With Data Group Locking** scheme used by the granular-locks implementation: data-group definitions and hierarchy, public and port-layer API, TCB locks, deferred state changes, ISR-only kernel critical-section helpers, event-list TOCTOU considerations, and current limitations.
b218d11 to
1132f5c
Compare
|



This PR adds support for granular locking to the FreeRTOS kernel.
Description
Granular locking introduces the concept of having localized locks per kernel data group for SMP configuration. This method is an optional replacement of the existing kernel locks and is controlled by a new port layer configuration, viz.,
portUSING_GRANULAR_LOCKS.Test Steps
A Common/Minimal demo runner for Espressif targets is included in this PR's branch under
FreeRTOS/Demo/Espressif_ESP32. The Check task polls every standard demo task on a 3-second cycle and prints per-testPASS/FAILlines in a Unity-style format, ending with a totals line and anOK/FAILEDverdict.Resources
To run the demo on an ESP32
1. Clone the public ESP-IDF fork and set up the build environment:
2. Build, flash, and monitor:
cd /path/to/FreeRTOS/FreeRTOS/Demo/Espressif_ESP32 idf.py set-target esp32 build flash monitor3. Observe the output:
Per-cycle:
Final summary (after the configured runtime, default 180 s):
4. Configure the runtime (optional):
The run length is set by
mainDEMO_DURATION_S(seconds;0runs until reset), overridden through theEXTRA_CFLAGSenvironment variable.EXTRA_CFLAGSis read at CMake configure time, so runidf.py fullcleanfirst (or use a fresh build directory) when you change it.Test Results
portUSING_GRANULAR_LOCKS=1configNUMBER_OF_CORES=2configRUN_MULTIPLE_PRIORITIES=0portUSING_GRANULAR_LOCKS=1configNUMBER_OF_CORES=2configRUN_MULTIPLE_PRIORITIES=1The Common/Minimal test updates and the ESP32 demo these results were produced
with are in the companion PR FreeRTOS/FreeRTOS#1434.
Legend:
⚠️IntQueue underconfigRUN_MULTIPLE_PRIORITIES=1: a receiver can be starvedbetween
xQueueReceive()removing a value from the queue andprvRecordValue_NormallyEmpty()storing it, so the round-end scan sees itmissing. It ran clean for 44 h 2 m of the 48 h sweep before failing; single priority completed the full 48 h clean.
TODO
⚠️IntQueue latch above. No panics, reboots or backtraces in either run. Full results and per-test tallies⛔test underconfigRUN_MULTIPLE_PRIORITIES=1(upstream Common/Minimal patches)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.