-
Notifications
You must be signed in to change notification settings - Fork 3k
Add Critical Section HAL API specification #5346
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
hal/critical_section_api.h
Outdated
* critical section or a nested call. The first call should | ||
* store the state prior to entering the critical section. | ||
*/ | ||
void hal_critical_section_enter(const bool in_nested_critical_section); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that makes more sense. I did it that way because the original implementation let you call enter multiple times and it would re-disable interrupts. But, that doesn't make much sense as it will assert if they've been re-enabled during the critical section.
@bulislaw are you happy with this now ? |
hal/critical_section_api.h
Outdated
|
||
/** Mark the start of a critical section | ||
* | ||
* This function is called directly by core_util_critical_section_enter on |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a bit sparse, can we add some info about multiple calls - as far as I understand that this function will be only called once (no need to handle enter-...-enter-exit). The same for exit. Are there any other assumptions or limitations we should mention?
hal/mbed_critical_section_api.c
Outdated
|
||
MBED_WEAK void hal_critical_section_exit() | ||
{ | ||
// FIXME |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is that fix me? if we don't know lets get rid of that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was in the original code, it was added here: Don't call __disable_irq for uVisor. It seems like it still needs resolving at some point so I didn't remove it.
platform/mbed_critical.c
Outdated
|
||
interrupt_enable_counter--; | ||
critical_section_reentrancy_counter--; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shall we assert at underflowing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose there's no harm in adding an assert, but it shouldn't underflow because it returns early if the counter is already 0.
Ah and also can we unify the name of mbed_critical_section_api.c to match the header. |
That seems reasonable. But, all of the current HAL files follow that naming scheme and I don't see the distinction from them e.g |
Ah ok fair enough. |
There are some issues with doxy can you please fix them. |
|
||
void hal_critical_section_enter(void) | ||
{ | ||
sd_nvic_critical_region_enter(&_sd_state); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
4 spaces indentation
hal/critical_section_api.h
Outdated
* function so it can be restored when exiting the critical section. | ||
* | ||
*/ | ||
void hal_critical_section_enter(void); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it documented anywhere that we are providing default implementation (reference where it can be found) ? I can not spot it, we shall mention it, so during porting, they do not reimplement it all over again
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a brief mention of it in the porting guide, which is in the PR description but I haven't added to the handbook yet. I can make it a bit clearer and point it to the default implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think about at least having a note here in API docs, that we are providing default implementation that can be overriden?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, I can make that clearer
Please not that this PR is just the code, the other part will be the PG section. |
Is that reviewed now? |
/morph build |
Build : SUCCESSBuild number : 355 Triggering tests/morph test |
Test : FAILUREBuild number : 168 |
|
It appears to be a timeout error on Failure is usually:
or sometimes:
fails here: mbed-os\TESTS\mbedmicro-rtos-mbed\rtostimer\main.cpp:115 slots = sem.wait(TEST_DELAY_MS + 1);
t.stop();
TEST_ASSERT_EQUAL(1, slots); from here: \mbed-os\rtos\Semaphore.cpp:46 int32_t Semaphore::wait(uint32_t millisec) {
osStatus_t stat = osSemaphoreAcquire(_id, millisec);
switch (stat) {
...
case osErrorTimeout:
return 0;
...
}
} |
As it was rebased, let's rerun the tests /morph build |
Build : SUCCESSBuild number : 415 Triggering tests/morph test |
Test : FAILUREBuild number : 205 |
As this was tested more than a week ago, restarting tests /morph build @scartmell-arm please look at results if any of these fail. |
Build : SUCCESSBuild number : 532 Triggering tests/morph test |
Exporter Build : SUCCESSBuild number : 146 |
Test : SUCCESSBuild number : 341 |
- Add function to HAL hal_in_critical_section() - Wrap assert in FEATURE_UVISOR macro
hal_critical_section_enter() is safe to call multiple times, however hal_critical_section_exit() is only called on the last exit from a critical section. This will cause a mismatch in the counter and the interrupt state will never be restored if the critical section is nested. Change this to a bool so that the interrupt save state is tracked for hal_in_critical_section() to work correctly.
/morph build |
Build : FAILUREBuild number : 843 |
Pipe closed exception /morph build |
Build : SUCCESSBuild number : 856 Triggering tests/morph test |
Exporter Build : FAILUREBuild number : 527 |
/morph export-build Another "Pipe closed" exception... |
Exporter Build : SUCCESSBuild number : 529 |
Test : FAILUREBuild number : 700 |
/morph test |
Test : SUCCESSBuild number : 706 |
Waiting for final approval from @alzix / @orenc17A (last round of review after changes that were requested earlier). |
Description
As discussed in NRF51_DK: core_util_are_interrupts_enabled wrong behavior when inside critical section #5198 there is a need for a HAL API specification for platform-specific Critical Section behaviors.
Specifically, the purpose of this pull request is to:
Provide a reliable method of detecting if the current program is running within a critical section.
The current method of checking if the program is in a critical section is to call
core_util_interrupts_enabled()
, under most circumstances this works as by default entering a critical section disables interrupts. Some platforms do not disable all interrupts when entering a critical section, causing this to fail.This PR provides a method
core_util_in_critical_section()
which specifically checks the state of the program.Move platform-specific implementations for critical sections from the User Facing API into the HAL.
Added the platform specific HAL functions
hal_critical_section_enter
andhal_critical_section_exit
which are called from the platform independent APIcore_util_critical_section_enter
andcore_util_critical_section_exit
.Added a weak default implementation for HAL API. The default implementation
matches the previous behavior stored in the User facing API:
before disabling and each successive call re-disables interrupts.
enter to the critical section. Nested calls are ignored.
Porting Guide
Implement the API declared in mbed-os/hal/critical_section_api.h. If the platform you are porting requires custom critical section behavior that is incompatible with the default (disabling all interrupts).
The functions defined in the header
hal_critical_section_enter
andhal_critical_section_exit
are called on the first entry to, and the last exit from the critical section respectively, any nested calls to enter critical sections do not call the HAL API functions.You must define the state changes that need to happen when entering a critical section. You should store this state in the critical section translation unit before setting to a state that is safe for the critical section. When
hal_critical_section_exit
is called the saved state should be restored.Status
IN DEVELOPMENT
TODO: