Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Real time embedded FreeRTOS mailing list 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT Training


Starving threads?

Posted by grygorek on March 4, 2016


I am using v8.2.3 on ARM CortexM0. I have noticed interesting behaviour. It is about using xSemaphoreTake and xSemaphoreGive. In a case when two running threads (same priority) use the same sempaphore then it may happen that the second thread will never get a chance to execute.

I think my problem is related to this (not sure): https://sourceforge.net/p/freertos/discussion/382005/thread/e981974b/

My application is more complex but I think the code below can explain the issue...

~~~~ SemaphoreHandle_t semH;

void Task1() { xSemaphoreTake( semH, 0xFFFFFFFF ); debug_print("000 "); xSemaphoreGive( semH ); }

void Task2() { xSemaphoreTake( semH, 0xFFFFFFFF ); debug_print("111 "); xSemaphoreGive( semH ); } ~~~~

I can see only "000 " being printed to the output. While debugging and stopped at the breakpoint at the line printing "000 " (Task1) the Task2 has status BLOCKED. However, when the xSemaphoreGive is executed from the Task1 the Task2 changes the status to READY. Beacause I dont switch the context in that moment the Task1 is still running and the xSemaphoreTake from the Task1 is executed again. Surprisingly it enters the locked section. The status of the Task2 changes to BLOCKED again. The loop continues and in result Task2 is never executed.

I know that adding the call to vPortYield() after the xSemaphoreGive solves the problem.

Not sure if this is correct/incorrect behaviour but at least some note in the documentation could help to avoid surprises.

I can provide more information about my configuration if needed.


Starving threads?

Posted by rtel on March 4, 2016

This is expected and documented (in the book at least) behaviour if you are using a semaphore in a tight loop from more than one task.

Older versions of FreeRTOS would yield after giving a semaphore if another task of equal or higher priority was waiting for the semaphore, but this had two perceived issues:

1) Really it breaks the scheduling policy, because a task should only yield to a higher priority task.

2) It can result in thrashing (rapidly switching back and forth) between tasks of equal priority with each task only performing a tiny amount of work in between each switch.

Now the behaviour has been 'corrected' in that a context switch is only performed if the task waiting for the semaphore has a higher priority - but this introduced the behaviour you have noticed.

If tasks of equal priority are using a semaphore in a tight loop then when the semaphore is given the other task will be unblocked, but not start executing until the end of the time slice. However, when the time slice ends the original task, if using the semaphore in a tight loop, will hold the semaphore again - and the unblocked task will simply re-enter the Blocked state until by co-incidence the time slice ends when the semaphore is not being held.

You have control over this; if you know you tasks are using a semaphore in this way then you can manually call taskYIELD() after the semaphore is given BUT that takes you back to a very inefficient thrashing execution pattern. Much better to yield manually only if you note that the time slice ended (the tick count incremented) while the semaphore. was being held.

[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]

Copyright (C) 2004-2010 Richard Barry. Copyright (C) 2010-2016 Real Time Engineers Ltd.
Any and all data, files, source code, html content and documentation included in the FreeRTOSTM distribution or available on this site are the exclusive property of Real Time Engineers Ltd.. See the files license.txt (included in the distribution) and this copyright notice for more information. FreeRTOSTM and FreeRTOS.orgTM are trade marks of Real Time Engineers Ltd.

Latest News:

FreeRTOS V9.0.0 is now available for download.

Free TCP/IP and file system demos for the RTOS

Sponsored Links

⇓ Now With No Code Size Limit! ⇓
⇑ Free Download Without Registering ⇑

FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Renesas Electronics Gold Alliance RTOS Partner.jpg

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Atmel RTOS partner supporting ARM Cortex-M3 and AVR32 microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Xilinx Microblaze and Zynq partner

Silicon Labs low power RTOS partner

Altera RTOS partner for Nios II and Cortex-A9 SoC

Freescale Alliance RTOS Member supporting ARM and ColdFire microcontrollers

Infineon ARM Cortex-M microcontrollers

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

Cypress RTOS partner supporting ARM Cortex-M3

Fujitsu RTOS partner supporting ARM Cortex-M3 and FM3

Microsemi (previously Actel) RTOS partner supporting ARM Cortex-M3

Atollic Partner

IAR Partner

Keil ARM Partner

Embedded Artists