FreeRTOS Support Archive
The FreeRTOS support forum is used to obtain active support directly from Real
Time Engineers Ltd. In return for using our top quality software and services for
free, we request you play fair and do your bit to help others too! Sign up
to receive notifications of new support topics then help where you can.
This is a read only archive of threads posted to the FreeRTOS support forum.
The archive is updated every week, so will not always contain the very latest posts.
Use these archive pages to search previous posts. Use the Live FreeRTOS Forum
link to reply to a post, or start a new support thread.
[FreeRTOS Home] [Live FreeRTOS Forum] [FAQ] [Archive Top] [February 2010 Threads] Semaphore monopolizationPosted by Andrew on February 23, 2010 FreeRTOS V6.0.2 and V5.0.2. It is possible to make taking semaphore impossible. It happens when tasks running on equal priorities try to take semaphore. First one (see task1 below) takes semaphore rarely for short time, the second one (see task2 below) takes semaphore for longer time but gives it back for a very short time. Takin semaphore in task1 never succeeds. Explicit taksYIELD() would walk around this problem, but it has significant impact on performance. Simply giving semaphore doesn't switch context to waiting task. I think it is a BUG but I can't make a bug request. Can anyone help? xSemaphoreHandle sem ;
void task1(void *pvParam) { while(1) { if (xSemaphoreTake(sem, 100)) { // BUG! We should be able to go into here, but it never happens xSemaphoreGive(sem) ;
vTaskDelay(100) ; } } }
void task2(void *pvParam) { while (1) { if (xSemaphoreTake(sem, 50)) { // Let's do something time consuming with semaphore taken vTaskDelay(100) ; xSemaphoreGive(sem) ; } } }
int main( void ) { prvSetupHardware();
xTaskHandle thDummy ; sem = xSemaphoreCreateMutex(); xTaskCreate(task1, (signed portCHAR*)"1", configMINIMAL_STACK_SIZE, NULL, 1, &thDummy) ; xTaskCreate(task2, (signed portCHAR*)"2", configMINIMAL_STACK_SIZE, NULL, 1, &thDummy) ;
vTaskStartScheduler(); }
RE: Semaphore monopolizationPosted by Dave on February 23, 2010 xSemaphoreGive() calls xQueueGenericSend(). Then within xQueueGenericSend() (on line 474 of V6.0.2) there is a call to xTaskRemoveFromEventList() which will return true if the queue send caused a task of EQUAL OR HIGHER priority to unblock (despite what the comment says). xTaskRemoveFromEventList() returning true will cause a yield, which is what you say should happen but isn't. It looks ok to me.
It is possible that in your example the timing is such that one task always yields to the other just at the end of the time slice, meaning that a yield is performed back again almost immediately. This would be legitimate behavior.
RE: Semaphore monopolizationPosted by Andrew on February 23, 2010 I is not about timing. Code below still shows the problem xSemaphoreHandle sem ; void task1(void *pvParam) { while(1) { if (xSemaphoreTake(sem, portMAX_DELAY)) { // BUG! We should be able to go into here, but it never happens xSemaphoreGive(sem) ; vTaskDelay(1000) ; } } }
void task2(void *pvParam) { while (1) { if (xSemaphoreTake(sem, 50)) { // Let's do something time consuming with semaphore taken vTaskDelay(100) ; xSemaphoreGive(sem) ; } } }
RE: Semaphore monopolizationPosted by Andrew on February 23, 2010 What is interesting, taskYIELD is called within xSemaphoreGive, but it looks like double context switch happens. Unblocked task was transferred to ready list, byt then taskYIELD cause context switch to the next one.
RE: Semaphore monopolizationPosted by Andras Brozso on February 24, 2010 Akuros, I think your code works as designed, too.
As I understand, in your example task2 will poll the system constantly and it excludes task1 processing with the semaphore. So task1 will - most likely - never got available time-slice to run (but it could happen, if the scheduler break task2 execution after sem.give and before the sem.take, but this is very unlikely), because they are on same priority level, and task2's sem.give will not force a context switch.
However, I'm not telling that there isn't bug in the scheduler, but I think this is not that scenario, where the scheduling fails.
RE: Semaphore monopolizationPosted by Andrew on February 24, 2010 Probably the code works as designed, but not as intended. task1 and task2 are on the same priority to keep priorities count as low as possible, to lower memory usage for semaphore and speedup scheduling mechanism. As I suspect a semaphore (as a queue) contains priority list of tasks waiting for the semaphore to unblock them on xSemaphoreGive. If it doesn't work as in example, semaphore could be built on simple volatile portBASE_TYPE, and could have significant lower memory usage.
However, I think it is still a bug, because in xQueueGenericSend there is an intended taskYIELD when we are giving back a semaphore which other task (on priority >= current) is waiting on.
RE: Semaphore monopolizationPosted by Richard on February 24, 2010 I'm not really following this.
It would appear to me that when a task gives a semaphore back then a context switch will be performed if there is a task of equal or higher priority that was blocked waiting for the semaphore. I think this is the expected and wanted behaviour.
If two tasks of equal priority then attempt to take the semaphore either could get it - there are no guarantees there.
Have I missed something?
Regards.
RE: Semaphore monopolizationPosted by Andrew on February 24, 2010 “If two tasks of equal priority then attempt to take the semaphore either could get it - there are no guarantees there.” But when a task is already blocked on semaphore, and semaphore holder gives it back the context switch should be performed to the next waiting for this semaphore. In the example context switch is performed, but context remains in task giving semaphore. So the otther task has no chance to take it. On xSemaphoreGive expected and wanted behaviour is that the context is switched to the next task waiting on the semaphore. And this task should be able to take it, because it is waiting for it. If there was such guarantee here, it would be really useful. Regards.
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.
|