Semaphores and blocking - wait a full tick?

scotthauck
Posts: 20
Joined: Fri Jul 26, 2019 5:50 pm

Semaphores and blocking - wait a full tick?

Postby scotthauck » Tue Jul 30, 2019 5:47 am

A question regarding blocking on a semaphore - if you block on a mutex and then the mutex is freed by another task, do you immediately (or quickly) unblock, or do you have to wait for a TICK of the OS?

I'm working on a two-thread application (one for computation, the other one servicing Wifi packets via an AsyncUDP listen function). To pass information between the two, I'll have "volatile" values controlled by a mutex. I would normally just block with an infinite timeout on the mutex to access the data, but if that means I wait for a full FreeOS Tick, that'll be a HUGE delay (1/100 of a second is a LOT). In which case I'll just use a timeout of 0, and busy-wait by calling a small delay in the code between attempts. Ugly, but with only two threads probably not an issue.

ESP_Angus
Posts: 2344
Joined: Sun May 08, 2016 4:11 am

Re: Semaphores and blocking - wait a full tick?

Postby ESP_Angus » Tue Jul 30, 2019 6:23 am

Hi scotthauck,

The short answer is: yes it will run immediately, but remembering that in an RTOS environment the highest priority runnable task will always be the one that runs (or, in ESP-IDF case, the highest priority runnable task on each of the two CPUs will be the ones that run).

The long answer is:

If the task blocked on the semaphore/etc is higher priority than the task giving the semaphore, it wakes immediately. (Or, if the blocked task is higher priority than the task running on the other core and it's also allowed to run on that core, it wakes immediately on the other core).

If the task blocked on the semaphore is lower priority than the tasks running on either CPU (or a single CPU, if the task is pinned to one core or the other) then it won't run until after the higher priority task(s) have stopped running for some reason (they block on a semaphore/queue/etc, or they call vTaskDelay()).

If the task blocked on the semaphore has the same priority as other running tasks, then it possibly may not run until other tasks with the same priority have either blocked or yielded.
scotthauck wrote: In which case I'll just use a timeout of 0, and busy-wait by calling a small delay in the code between attempts. Ugly, but with only two threads probably not an issue.
This approach will not work as expected in an RTOS environment. Delaying with vTaskDelay() is for a minimum of 1 RTOS tick. Busy-waiting by spinning is the same as running, so a high priority task which spins will block all lower priority tasks from running on that CPU.

The best solution in an RTOS environment is to use semaphores/queues/etc.

scotthauck
Posts: 20
Joined: Fri Jul 26, 2019 5:50 pm

Re: Semaphores and blocking - wait a full tick?

Postby scotthauck » Tue Jul 30, 2019 3:20 pm

Excellent - exactly what I was hoping it would do!

BTW, is there either a way to list all the processes running on the ESP32, or an architecture document on the Arduino version of the ESP32 that would walk through this? I *think* I'm setting things up to have just two threads, with at least one not locked to a specific CPU (the callback for the Wifi, and the normal arduino setup/loop thread), but I realize there might actually be others I should be aware of.

Thanks!

Scott

scotthauck
Posts: 20
Joined: Fri Jul 26, 2019 5:50 pm

Re: Semaphores and blocking - wait a full tick?

Postby scotthauck » Tue Jul 30, 2019 5:51 pm

Never mind, looks like I found it: uxTaskGetSystemState and uxTaskGetNumberOfTasks.

Who is online

Users browsing this forum: No registered users and 117 guests