diff --git a/src/system/freertos_plus_tcp/system.c b/src/system/freertos_plus_tcp/system.c index 726f9236c..f4f1606b2 100644 --- a/src/system/freertos_plus_tcp/system.c +++ b/src/system/freertos_plus_tcp/system.c @@ -233,6 +233,38 @@ z_result_t _z_condvar_wait(_z_condvar_t *cv, _z_mutex_t *m) { return _Z_RES_OK; } + +z_result_t _z_condvar_wait_until(_z_condvar_t *cv, _z_mutex_t *m, const z_clock_t *abstime, bool *timeout) { + if (!cv || !m) { + return _Z_ERR_GENERIC; + } + + TickType_t now = xTaskGetTickCount(); + TickType_t target_time = *abstime; + TickType_t block_duration = (target_time > now) ? (target_time - now) : 0; + + xSemaphoreTake(cv->mutex, portMAX_DELAY); + cv->waiters++; + xSemaphoreGive(cv->mutex); + + _z_mutex_unlock(m); + + bool timed_out = xSemaphoreTake(cv->sem, block_duration) == pdFALSE; + + _z_mutex_lock(m); + + if (timed_out) { + xSemaphoreTake(cv->mutex, portMAX_DELAY); + cv->waiters--; + xSemaphoreGive(cv->mutex); + } + + if (timeout != NULL) { + *timeout = timed_out; + } + + return _Z_RES_OK; +} #endif // Z_MULTI_THREAD == 1 /*------------------ Sleep ------------------*/ diff --git a/src/system/mbed/system.cpp b/src/system/mbed/system.cpp index 627293ce0..425fb1e4d 100644 --- a/src/system/mbed/system.cpp +++ b/src/system/mbed/system.cpp @@ -171,6 +171,39 @@ z_result_t _z_condvar_wait(_z_condvar_t *cv, _z_mutex_t *m) { return _Z_RES_OK; } + +z_result_t _z_condvar_wait_until(_z_condvar_t *cv, _z_mutex_t *m, const z_clock_t *abstime, bool *timeout) { + if (!cv || !m) { + return _Z_ERR_GENERIC; + } + + auto &cond_var = *(condvar *)*cv; + + auto target_time = + Kernel::Clock::time_point(Kernel::Clock::duration(abstime->tv_sec * 1000LL + abstime->tv_nsec / 1000000)); + + cond_var.mutex.lock(); + cond_var.waiters++; + cond_var.mutex.unlock(); + + _z_mutex_unlock(m); + + bool timed_out = cond_var.sem.try_acquire_until(target_time) == false; + + _z_mutex_lock(m); + + if (timed_out) { + cond_var.mutex.lock(); + cond_var.waiters--; + cond_var.mutex.unlock(); + } + + if (timeout != NULL) { + *timeout = timed_out; + } + + return _Z_RES_OK; +} #endif // Z_FEATURE_MULTI_THREAD == 1 /*------------------ Sleep ------------------*/