You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
If two different threads on the same core attempt an esp_ipc_call() at the same time it is possible for one to be woken early.
Steps to reproduce
In two different threads on the same core, esp_ipc_call() esp_ipc_call_blocking()
If the function in esp_ipc_call() takes a while to run or blocks, a second thread calling esp_ipc_call_blocking() can be woken before it should be.
Theoretical analysis:
static void IRAM_ATTR ipc_task(void* arg)
{
...
// Original code
if (s_ipc_wait[cpuid] == IPC_WAIT_FOR_START) {
xSemaphoreGive(s_ipc_ack[cpuid]);
}
(*func)(arg);
if (s_ipc_wait[cpuid] == IPC_WAIT_FOR_END) {
xSemaphoreGive(s_ipc_ack[cpuid]);
}
...
}
The first pass in ipc_task() handling the esp_ipc_call() will give the ack semaphore (as s_ipc_wait[]=IPC_WAIT_FOR_START) and then execute (*func)(arg). When the ack semaphore is given, that esp_ipc_call() can exit and the call to esp_ipc_call_blocking() can now update s_ipc_wait[] and s_ipc_ack[]. When (*func)(arg) returns, it checks the new value of s_ipc_wait[] which is now IPC_WAIT_FOR_END and then gives the new s_ipc_ack[] before the the (*func)() from esp_ipc_call_blocking() had a chance to be called. Both of these need to be cached first.
Problem Description
If two different threads on the same core attempt an esp_ipc_call() at the same time it is possible for one to be woken early.
Steps to reproduce
In two different threads on the same core,
esp_ipc_call()
esp_ipc_call_blocking()
If the function in esp_ipc_call() takes a while to run or blocks, a second thread calling esp_ipc_call_blocking() can be woken before it should be.
Theoretical analysis:
The first pass in
ipc_task()
handling theesp_ipc_call()
will give the ack semaphore (ass_ipc_wait[]=IPC_WAIT_FOR_START
) and then execute(*func)(arg)
. When the ack semaphore is given, thatesp_ipc_call()
can exit and the call toesp_ipc_call_blocking()
can now updates_ipc_wait[]
ands_ipc_ack[]
. When(*func)(arg)
returns, it checks the new value ofs_ipc_wait[]
which is nowIPC_WAIT_FOR_END
and then gives the news_ipc_ack[]
before the the(*func)()
fromesp_ipc_call_blocking()
had a chance to be called. Both of these need to be cached first.The text was updated successfully, but these errors were encountered: