Skip to content
Snippets Groups Projects
Commit 01d98974 authored by Federico's avatar Federico
Browse files

Added memory barrier to saveContext() to prevent a race condition found in the new stm32f429 board.

parent 6abf583f
Branches
Tags
No related merge requests found
Changelog for Miosix np embedded OS
- Added memory barrier to saveContext() to prevent a race condition found in
the new stm32f429 board.
- Now Makefile.inc has no predefined board. This has been done in order to
avoid mistakenly compiling for the wrong board.
- Fixed bug in testsuite: it failed compiling with exceptions disabled due
......
......@@ -62,6 +62,15 @@ extern volatile unsigned int *ctxsave;
* Save context from an interrupt<br>
* Must be the first line of an IRQ where a context switch can happen.
* The IRQ must be "naked" to prevent the compiler from generating context save.
*
* A note on the dmb instruction, without it a race condition was observed
* between pauseKernel() and IRQfindNextThread(). pauseKernel() uses an strex
* instruction to store a value in the global variable kernel_running which is
* tested by the context switch code in IRQfindNextThread(). Without the memory
* barrier IRQfindNextThread() would occasionally read the previous value and
* perform a context switch while the kernel was paused, leading to deadlock.
* The failure was only observed within the exception_test() in the testsuite
* running on the stm32f429zi_stm32f4discovery.
*/
#define saveContext() \
{ \
......@@ -70,6 +79,7 @@ extern volatile unsigned int *ctxsave;
"ldr r0, =ctxsave \n\t" /*get current context*/ \
"ldr r0, [r0] \n\t" \
"stmia r0, {r1,r4-r11} \n\t" /*save PROCESS sp + r4-r11*/ \
"dmb \n\t" \
); \
}
......
......@@ -63,6 +63,15 @@ extern volatile unsigned int *ctxsave;
* Save context from an interrupt<br>
* Must be the first line of an IRQ where a context switch can happen.
* The IRQ must be "naked" to prevent the compiler from generating context save.
*
* A note on the dmb instruction, without it a race condition was observed
* between pauseKernel() and IRQfindNextThread(). pauseKernel() uses an strex
* instruction to store a value in the global variable kernel_running which is
* tested by the context switch code in IRQfindNextThread(). Without the memory
* barrier IRQfindNextThread() would occasionally read the previous value and
* perform a context switch while the kernel was paused, leading to deadlock.
* The failure was only observed within the exception_test() in the testsuite
* running on the stm32f429zi_stm32f4discovery.
*/
#define saveContext() \
{ \
......@@ -71,6 +80,7 @@ extern volatile unsigned int *ctxsave;
"ldr r0, =ctxsave \n\t" /*get current context*/ \
"ldr r0, [r0] \n\t" \
"stmia r0, {r1,r4-r11} \n\t" /*save PROCESS sp + r4-r11*/ \
"dmb \n\t" \
); \
}
......
......@@ -62,6 +62,15 @@ extern volatile unsigned int *ctxsave;
* Save context from an interrupt<br>
* Must be the first line of an IRQ where a context switch can happen.
* The IRQ must be "naked" to prevent the compiler from generating context save.
*
* A note on the dmb instruction, without it a race condition was observed
* between pauseKernel() and IRQfindNextThread(). pauseKernel() uses an strex
* instruction to store a value in the global variable kernel_running which is
* tested by the context switch code in IRQfindNextThread(). Without the memory
* barrier IRQfindNextThread() would occasionally read the previous value and
* perform a context switch while the kernel was paused, leading to deadlock.
* The failure was only observed within the exception_test() in the testsuite
* running on the stm32f429zi_stm32f4discovery.
*/
#define saveContext() \
{ \
......@@ -70,6 +79,7 @@ extern volatile unsigned int *ctxsave;
"ldr r0, =ctxsave \n\t" /*get current context*/ \
"ldr r0, [r0] \n\t" \
"stmia r0, {r1,r4-r11} \n\t" /*save PROCESS sp + r4-r11*/ \
"dmb \n\t" \
); \
}
......
......@@ -67,6 +67,15 @@ extern volatile unsigned int *ctxsave;
* Save context from an interrupt<br>
* Must be the first line of an IRQ where a context switch can happen.
* The IRQ must be "naked" to prevent the compiler from generating context save.
*
* A note on the dmb instruction, without it a race condition was observed
* between pauseKernel() and IRQfindNextThread(). pauseKernel() uses an strex
* instruction to store a value in the global variable kernel_running which is
* tested by the context switch code in IRQfindNextThread(). Without the memory
* barrier IRQfindNextThread() would occasionally read the previous value and
* perform a context switch while the kernel was paused, leading to deadlock.
* The failure was only observed within the exception_test() in the testsuite
* running on the stm32f429zi_stm32f4discovery.
*/
#define saveContext() \
{ \
......@@ -77,7 +86,7 @@ extern volatile unsigned int *ctxsave;
" lsls r2, lr, #27 \n"/*check if bit #4 is set */ \
" bmi 0f \n" \
" vstmia.32 r0, {s16-s31} \n"/*save s16-s31 if we need*/ \
"0: \n" \
"0: dmb \n" \
); \
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment