add a task completion semaphore to guarantee async_context task is finished before async_context cleanup finishes (#2587)
Some checks are pending
Bazel presubmit checks / bazel-build-check (macos-latest) (push) Waiting to run
Bazel presubmit checks / bazel-build-check (ubuntu-latest) (push) Waiting to run
Bazel presubmit checks / other-bazel-checks (push) Waiting to run
Check Configs / check-configs (push) Waiting to run
CMake / build (push) Waiting to run
Build on macOS / build (push) Waiting to run
Build on Windows / build (push) Waiting to run

This commit is contained in:
Graham Sanderson 2025-07-23 13:35:26 -05:00 committed by GitHub
parent c650739c4c
commit d011e8abd4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 11 additions and 0 deletions

View file

@ -73,6 +73,7 @@ static void async_context_task(__unused void *vself) {
async_context_freertos_release_lock(&self->core); async_context_freertos_release_lock(&self->core);
__sev(); // it is possible regular code is waiting on a WFE on the other core __sev(); // it is possible regular code is waiting on a WFE on the other core
} while (!self->task_should_exit); } while (!self->task_should_exit);
xSemaphoreGive(self->task_complete_sem);
vTaskDelete(NULL); vTaskDelete(NULL);
} }
@ -113,6 +114,7 @@ bool async_context_freertos_init(async_context_freertos_t *self, async_context_f
assert(config->task_stack); assert(config->task_stack);
self->lock_mutex = xSemaphoreCreateRecursiveMutexStatic(&self->lock_mutex_buf); self->lock_mutex = xSemaphoreCreateRecursiveMutexStatic(&self->lock_mutex_buf);
self->work_needed_sem = xSemaphoreCreateBinaryStatic(&self->work_needed_sem_buf); self->work_needed_sem = xSemaphoreCreateBinaryStatic(&self->work_needed_sem_buf);
self->task_complete_sem = xSemaphoreCreateBinaryStatic(&self->task_complete_sem_buf);
self->timer_handle = xTimerCreateStatic( "async_context_timer", // Just a text name, not used by the kernel. self->timer_handle = xTimerCreateStatic( "async_context_timer", // Just a text name, not used by the kernel.
portMAX_DELAY, portMAX_DELAY,
pdFALSE, // The timers will auto-reload themselves when they expire. pdFALSE, // The timers will auto-reload themselves when they expire.
@ -129,6 +131,7 @@ bool async_context_freertos_init(async_context_freertos_t *self, async_context_f
#else #else
self->lock_mutex = xSemaphoreCreateRecursiveMutex(); self->lock_mutex = xSemaphoreCreateRecursiveMutex();
self->work_needed_sem = xSemaphoreCreateBinary(); self->work_needed_sem = xSemaphoreCreateBinary();
self->task_complete_sem = xSemaphoreCreateBinary();
self->timer_handle = xTimerCreate( "async_context_timer", // Just a text name, not used by the kernel. self->timer_handle = xTimerCreate( "async_context_timer", // Just a text name, not used by the kernel.
portMAX_DELAY, portMAX_DELAY,
pdFALSE, // The timers will auto-reload themselves when they expire. pdFALSE, // The timers will auto-reload themselves when they expire.
@ -171,6 +174,9 @@ void async_context_freertos_deinit(async_context_t *self_base) {
async_context_freertos_t *self = (async_context_freertos_t *)self_base; async_context_freertos_t *self = (async_context_freertos_t *)self_base;
if (self->task_handle) { if (self->task_handle) {
async_context_execute_sync(self_base, end_task_func, self_base); async_context_execute_sync(self_base, end_task_func, self_base);
if (self->task_complete_sem) {
xSemaphoreTake(self->task_complete_sem, portMAX_DELAY);
}
} }
if (self->timer_handle) { if (self->timer_handle) {
xTimerDelete(self->timer_handle, 0); xTimerDelete(self->timer_handle, 0);
@ -181,6 +187,9 @@ void async_context_freertos_deinit(async_context_t *self_base) {
if (self->work_needed_sem) { if (self->work_needed_sem) {
vSemaphoreDelete(self->work_needed_sem); vSemaphoreDelete(self->work_needed_sem);
} }
if (self->task_complete_sem) {
vSemaphoreDelete(self->task_complete_sem);
}
memset(self, 0, sizeof(*self)); memset(self, 0, sizeof(*self));
} }

View file

@ -75,11 +75,13 @@ struct async_context_freertos {
async_context_t core; async_context_t core;
SemaphoreHandle_t lock_mutex; SemaphoreHandle_t lock_mutex;
SemaphoreHandle_t work_needed_sem; SemaphoreHandle_t work_needed_sem;
SemaphoreHandle_t task_complete_sem;
TimerHandle_t timer_handle; TimerHandle_t timer_handle;
TaskHandle_t task_handle; TaskHandle_t task_handle;
#if configSUPPORT_STATIC_ALLOCATION #if configSUPPORT_STATIC_ALLOCATION
StaticSemaphore_t lock_mutex_buf; StaticSemaphore_t lock_mutex_buf;
StaticSemaphore_t work_needed_sem_buf; StaticSemaphore_t work_needed_sem_buf;
StaticSemaphore_t task_complete_sem_buf;
StaticTimer_t timer_buf; StaticTimer_t timer_buf;
StaticTask_t task_buf; StaticTask_t task_buf;
#endif #endif