Richard,
I’m making videos of FreeRTOS tutorial (http://www.socialledge.com/sjsu/index.php?title=FreeRTOS_Tutorial) and I’ve noticed the priority inversion anomaly in FreeRTOS. In my demo program below, it makes no difference if the semaphore is a mutex or a binary semaphore. In either case, I see the same output, but I think it lower priority tasks should get equal access.
Output (regardless if semaphore is a mutex or semaphore):
task4 got sem. Will use it …
task3 got sem. Will use it …
task4 got sem. Will use it …
task3 got sem. Will use it …
task4 got sem. Will use it …
xSemaphoreHandle sd_card_lock = 0;
void my_task(void *p)
{
while(1) {
if(xSemaphoreTake(sd_card_lock, 999999)) {
printf(”%s got sem. Will use it … n”, (char*)p);
xSemaphoreGive(sd_card_lock);
}
vTaskDelay(1);
}
}
void main( void )
{
sd_card_lock = xSemaphoreCreateMutex();
//vSemaphoreCreateBinary(sd_card_lock);
xTaskCreate(my_task, (signed char*) “t1″, 1024, (void*)”task1”, 2, NULL );
xTaskCreate(my_task, (signed char*) “t2″, 1024, (void*)”task2”, 2, NULL );
xTaskCreate(my_task, (signed char*) “t3″, 1024, (void*)”task3”, 3, NULL );
xTaskCreate(my_task, (signed char*) “t4″, 1024, (void*)”task4”, 3, NULL );
vTaskStartScheduler();
}
If all tasks have the same priority, then we see every task taking turn, again regardless if the semaphore is a mutex or binary. But with a mutex, it should be the same behavior but it’s not :( Can you please educate me?
Preet
Mutex Priority Inversion Anamoly
Mutex Priority Inversion Anamoly
Why would you expect the priority 1 or 2 task to every get the semaphore?
When Task 4 gets the semaphore, everyone else lines up on it and waits for it.
When Task 4 gives the semaphore back, Task3, since it is the highest priority task will get it.
While Task 3 is outputing its message, my guess is that Task 4 finishes its 1 tick wait, and then puts itself in line for the semaphore.
When Task 3 finishes, task 4 get the semaphore because it is the highest priority task waiting on the semaphore. Making the semaphore into a mutex just says that when Task 4 starts its wait on the semaphore, Task 3 gets a temporary boost in priority to that of Task 4 (the priority inversion logic) . If all tasks are the same priority, then the priority doesn’t select which task gets chosen, and among equal priority tasks, the one waiting the longest it chosen first.
When Task 4 gives the semaphore back, Task3, since it is the highest priority task will get it.
While Task 3 is outputing its message, my guess is that Task 4 finishes its 1 tick wait, and then puts itself in line for the semaphore.
When Task 3 finishes, task 4 get the semaphore because it is the highest priority task waiting on the semaphore. Making the semaphore into a mutex just says that when Task 4 starts its wait on the semaphore, Task 3 gets a temporary boost in priority to that of Task 4 (the priority inversion logic) . If all tasks are the same priority, then the priority doesn’t select which task gets chosen, and among equal priority tasks, the one waiting the longest it chosen first.