-
Notifications
You must be signed in to change notification settings - Fork 9
Description
The __SIGNAL macro is unsafe and should not be used
Issues with signalling a thread
Using the __SIGNAL macro, a task or ISR can signal a thread to wake up immediately. This can lead to inconsistencies in a number of ways. I will illustrate this with two examples.
Example 1: using __SIGNAL inside a task function
Due to the way the scheduler works, it will repeatedly select the highest priority thread, even if the current thread hasn't committed its changes yet (Is in the THREAD_FINISHED state). This can lead to an inconsistency when Thread1, with lower priority, signals Thread2, with higher priority. Thread1 will continue executing, but before it can commit its changes the scheduler will start executing Thread2. If Thread2 then signals Thread1 and finishes executing, Thread1 will start over without having committed its previous changes. These changes will be overwritten, which leaves the system in an inconsistent state.
Example 2: using __SIGNAL inside an ISR
If Thread1 has executed and has not yet started committing its changes, and an ISR signals Thread1, then Thread1 will stop committing its changes and restart execution. For the same reason as before, this can lead to an inconsistent system state. This is hard to produce in practice since the time interval where this issue can occur is very small.
Potential solution
Thread signaling could be delayed until after a thread has fully committed its changes. This would remove the condition that causes the inconsistencies.
OR, the break statement here could be removed, this would make the tick function run entirely without having to call it twice. But this also requires a rework of the state machine.
Lines 75 to 78 in 2a95405
| else{ | |
| thread->next = (void *)(((task_t)thread->next)(buf)); | |
| thread->state = TASK_FINISHED; | |
| break; |