Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support waiting on condition variable until a specific time point #665

Merged
merged 22 commits into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
5b9b415
Add z_clock_advance functions
bjsowa Sep 15, 2024
7049dcc
Add z_condvar_timedwait function
bjsowa Sep 15, 2024
72d794f
Use monotonic clock in unix port of condvar
bjsowa Sep 15, 2024
24ba4a3
Merge remote-tracking branch 'eclipse/main' into feature/condvar_time…
bjsowa Nov 17, 2024
c86205f
Add timeout argument
bjsowa Nov 17, 2024
8104433
Fix build on macos
bjsowa Nov 18, 2024
566f7a3
Add missing docstrings
bjsowa Nov 18, 2024
341d1f0
Use POSIX implementation in arduino, espidf and zephyr ports
bjsowa Nov 18, 2024
e768f9d
Add missing errno includes
bjsowa Nov 18, 2024
600f3fe
Fix formatting
bjsowa Nov 18, 2024
8dcf271
Merge branch 'main' into feature/condvar_timedwait
bjsowa Dec 7, 2024
8ae9f43
Implement z_clock_advance for mbed port
bjsowa Dec 7, 2024
7658248
Implement z_clock_advance for freertos_plus_tcp port
bjsowa Dec 7, 2024
7c29df8
Implement z_clock_advance for windows port
bjsowa Dec 7, 2024
08448a1
Implement z_condvar_wait_until in windows port
bjsowa Dec 7, 2024
d35e6f6
Merge branch 'main' into feature/condvar_timedwait
bjsowa Dec 10, 2024
6925cd5
Implement z_condvar_wait_until for freertos_plus_tcp and mbed ports
bjsowa Dec 10, 2024
4890d42
Implement z_condvar_wait_until for rpi_pico port
bjsowa Dec 10, 2024
d86cc51
Merge remote-tracking branch 'eclipse/main' into feature/condvar_time…
bjsowa Dec 12, 2024
59f88aa
Add opencv and flipper clock advance implementations
bjsowa Dec 15, 2024
ff7dc08
Add emscripten implementation
bjsowa Dec 15, 2024
284e3ba
Return a timeout result code instead of setting timeout variable
bjsowa Dec 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions include/zenoh-pico/system/common/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ z_result_t _z_condvar_drop(_z_condvar_t *cv);
z_result_t _z_condvar_signal(_z_condvar_t *cv);
z_result_t _z_condvar_signal_all(_z_condvar_t *cv);
z_result_t _z_condvar_wait(_z_condvar_t *cv, _z_mutex_t *m);
z_result_t _z_condvar_wait_until(_z_condvar_t *cv, _z_mutex_t *m, const z_clock_t *abstime);

/**
* Initializes a condition variable.
Expand Down Expand Up @@ -323,6 +324,22 @@ z_result_t z_condvar_signal(z_loaned_condvar_t *cv);
*/
z_result_t z_condvar_wait(z_loaned_condvar_t *cv, z_loaned_mutex_t *m);

/**
* Waits for a signal on the condition variable while holding a mutex until a specified time.
*
* The calling thread is blocked until the condition variable is signaled or the timeout occurs.
* The associated mutex must be locked by the calling thread, and it will be automatically unlocked while waiting.
*
* Parameters:
* cv: Pointer to a :c:type:`z_loaned_condvar_t` on which to wait.
* m: Pointer to a :c:type:`z_loaned_mutex_t` that will be unlocked during the wait.
* abstime: Absolute end time.
*
* Returns:
* ``0`` if the wait is successful, ``Z_ETIMEDOUT`` if a timeout occurred, other negative value otherwise.
*/
z_result_t z_condvar_wait_until(z_loaned_condvar_t *cv, z_loaned_mutex_t *m, const z_clock_t *abstime);

/*------------------ Sleep ------------------*/
/**
* Suspends execution for a specified amount of time in microseconds.
Expand Down Expand Up @@ -396,6 +413,33 @@ unsigned long z_clock_elapsed_ms(z_clock_t *time);
*/
unsigned long z_clock_elapsed_s(z_clock_t *time);

/**
* Offsets the clock by a specified duration in microseconds.
*
* Parameters:
* clock: Pointer to a `z_clock_t` to offset.
* duration: The duration in microseconds.
*/
void z_clock_advance_us(z_clock_t *clock, unsigned long duration);

/**
* Offsets the clock by a specified duration in milliseconds.
*
* Parameters:
* clock: Pointer to a `z_clock_t` to offset.
* duration: The duration in milliseconds.
*/
void z_clock_advance_ms(z_clock_t *clock, unsigned long duration);

/**
* Offsets the clock by a specified duration in seconds.
*
* Parameters:
* clock: Pointer to a `z_clock_t` to offset.
* duration: The duration in seconds.
*/
void z_clock_advance_s(z_clock_t *clock, unsigned long duration);

/*------------------ Time ------------------*/

/**
Expand Down
1 change: 1 addition & 0 deletions include/zenoh-pico/utils/result.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ typedef enum {
_Z_ERR_OVERFLOW = -74,
_Z_ERR_SESSION_CLOSED = -73,
Z_EDESERIALIZE = -72,
Z_ETIMEDOUT = -71,

_Z_ERR_GENERIC = -128
} _z_res_t;
Expand Down
40 changes: 38 additions & 2 deletions src/system/arduino/esp32/system.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
//

#include <Arduino.h>
#include <errno.h>
#include <esp_heap_caps.h>
#include <esp_random.h>
#include <stddef.h>
Expand Down Expand Up @@ -114,15 +115,28 @@ z_result_t _z_mutex_try_lock(_z_mutex_t *m) { _Z_CHECK_SYS_ERR(pthread_mutex_try
z_result_t _z_mutex_unlock(_z_mutex_t *m) { _Z_CHECK_SYS_ERR(pthread_mutex_unlock(m)); }

/*------------------ Condvar ------------------*/
z_result_t _z_condvar_init(_z_condvar_t *cv) { _Z_CHECK_SYS_ERR(pthread_cond_init(cv, NULL)); }
z_result_t _z_condvar_init(_z_condvar_t *cv) {
pthread_condattr_t attr;
pthread_condattr_init(&attr);
pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
_Z_CHECK_SYS_ERR(pthread_cond_init(cv, &attr));
}

z_result_t _z_condvar_drop(_z_condvar_t *cv) { _Z_CHECK_SYS_ERR(pthread_cond_destroy(cv)); }

z_result_t _z_condvar_signal(_z_condvar_t *cv) { _Z_CHECK_SYS_ERR(pthread_cond_signal(cv)); }

z_result_t _z_condvar_signal_all(_z_condvar_t *cv) { _Z_CHECK_SYS_ERR(pthread_cond_broadcast(cv)); }

z_result_t _z_condvar_wait(_z_condvar_t *cv, _z_mutex_t *m) { _Z_CHECK_SYS_ERR(pthread_cond_wait(cv, m)); }
z_result_t _z_condvar_wait_until(_z_condvar_t *cv, _z_mutex_t *m, const z_clock_t *abstime) {
int error = pthread_cond_timedwait(cv, m, abstime);

if (error == ETIMEDOUT) {
return Z_ETIMEDOUT;
}

_Z_CHECK_SYS_ERR(error);
}
#endif // Z_FEATURE_MULTI_THREAD == 1

/*------------------ Sleep ------------------*/
Expand Down Expand Up @@ -177,6 +191,28 @@ unsigned long z_clock_elapsed_s(z_clock_t *instant) {
return elapsed;
}

void z_clock_advance_us(z_clock_t *clock, unsigned long duration) {
clock->tv_sec += duration / 1000000;
clock->tv_nsec += (duration % 1000000) * 1000;

if (clock->tv_nsec >= 1000000000) {
clock->tv_sec += 1;
clock->tv_nsec -= 1000000000;
}
}

void z_clock_advance_ms(z_clock_t *clock, unsigned long duration) {
clock->tv_sec += duration / 1000;
clock->tv_nsec += (duration % 1000) * 1000000;

if (clock->tv_nsec >= 1000000000) {
clock->tv_sec += 1;
clock->tv_nsec -= 1000000000;
}
}

void z_clock_advance_s(z_clock_t *clock, unsigned long duration) { clock->tv_sec += duration; }

/*------------------ Time ------------------*/
z_time_t z_time_now(void) {
z_time_t now;
Expand Down
23 changes: 23 additions & 0 deletions src/system/arduino/opencr/system.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ z_result_t _z_condvar_signal(_z_condvar_t *cv) { return -1; }
z_result_t _z_condvar_signal_all(_z_condvar_t *cv) { return -1; }

z_result_t _z_condvar_wait(_z_condvar_t *cv, _z_mutex_t *m) { return -1; }
z_result_t _z_condvar_wait_until(_z_condvar_t *cv, _z_mutex_t *m, const z_clock_t *abstime) { return -1; }
#endif // Z_FEATURE_MULTI_THREAD == 1

/*------------------ Sleep ------------------*/
Expand Down Expand Up @@ -160,6 +161,28 @@ unsigned long z_clock_elapsed_s(z_clock_t *instant) {
return elapsed;
}

void z_clock_advance_us(z_clock_t *clock, unsigned long duration) {
clock->tv_sec += duration / 1000000;
clock->tv_nsec += (duration % 1000000) * 1000;

if (clock->tv_nsec >= 1000000000) {
clock->tv_sec += 1;
clock->tv_nsec -= 1000000000;
}
}

void z_clock_advance_ms(z_clock_t *clock, unsigned long duration) {
clock->tv_sec += duration / 1000;
clock->tv_nsec += (duration % 1000) * 1000000;

if (clock->tv_nsec >= 1000000000) {
clock->tv_sec += 1;
clock->tv_nsec -= 1000000000;
}
}

void z_clock_advance_s(z_clock_t *clock, unsigned long duration) { clock->tv_sec += duration; }

/*------------------ Time ------------------*/
z_time_t z_time_now(void) {
z_time_t now;
Expand Down
3 changes: 3 additions & 0 deletions src/system/common/platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,5 +61,8 @@ z_result_t z_condvar_drop(z_moved_condvar_t *cv) { return _z_condvar_drop(&cv->_

z_result_t z_condvar_signal(z_loaned_condvar_t *cv) { return _z_condvar_signal(cv); }
z_result_t z_condvar_wait(z_loaned_condvar_t *cv, z_loaned_mutex_t *m) { return _z_condvar_wait(cv, m); }
z_result_t z_condvar_wait_until(z_loaned_condvar_t *cv, z_loaned_mutex_t *m, const z_clock_t *abstime) {
return _z_condvar_wait_until(cv, m, abstime);
}

#endif // Z_FEATURE_MULTI_THREAD == 1
30 changes: 28 additions & 2 deletions src/system/emscripten/system.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
//

#include <emscripten/html5.h>
#include <errno.h>
#include <pthread.h>
#include <stddef.h>
#include <stdio.h>
Expand Down Expand Up @@ -69,7 +70,12 @@ z_result_t _z_mutex_try_lock(_z_mutex_t *m) { _Z_CHECK_SYS_ERR(pthread_mutex_try
z_result_t _z_mutex_unlock(_z_mutex_t *m) { _Z_CHECK_SYS_ERR(pthread_mutex_unlock(m)); }

/*------------------ Condvar ------------------*/
z_result_t _z_condvar_init(_z_condvar_t *cv) { _Z_CHECK_SYS_ERR(pthread_cond_init(cv, 0)); }
z_result_t _z_condvar_init(_z_condvar_t *cv) {
pthread_condattr_t attr;
pthread_condattr_init(&attr);
pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
_Z_CHECK_SYS_ERR(pthread_cond_init(cv, &attr));
}

z_result_t _z_condvar_drop(_z_condvar_t *cv) { _Z_CHECK_SYS_ERR(pthread_cond_destroy(cv)); }

Expand All @@ -78,6 +84,20 @@ z_result_t _z_condvar_signal(_z_condvar_t *cv) { _Z_CHECK_SYS_ERR(pthread_cond_s
z_result_t _z_condvar_signal_all(_z_condvar_t *cv) { _Z_CHECK_SYS_ERR(pthread_cond_broadcast(cv)); }

z_result_t _z_condvar_wait(_z_condvar_t *cv, _z_mutex_t *m) { _Z_CHECK_SYS_ERR(pthread_cond_wait(cv, m)); }

z_result_t _z_condvar_wait_until(_z_condvar_t *cv, _z_mutex_t *m, const z_clock_t *abstime) {
struct timespec ts;
ts.tv_sec = (time_t)(*abstime / 1000);
ts.tv_nsec = (long)((*abstime - (ts.tv_sec * 1000)) * 1000000);

int error = pthread_cond_timedwait(cv, m, &ts);

if (error == ETIMEDOUT) {
return Z_ETIMEDOUT;
}

_Z_CHECK_SYS_ERR(error);
}
#endif // Z_FEATURE_MULTI_THREAD == 1

/*------------------ Sleep ------------------*/
Expand Down Expand Up @@ -111,7 +131,13 @@ unsigned long z_clock_elapsed_us(z_clock_t *instant) { return z_clock_elapsed_ms

unsigned long z_clock_elapsed_ms(z_clock_t *instant) { return z_time_elapsed_ms(instant); }

unsigned long z_clock_elapsed_s(z_clock_t *instant) { return z_time_elapsed_ms(instant) * 1000; }
unsigned long z_clock_elapsed_s(z_clock_t *instant) { return z_time_elapsed_ms(instant) / 1000; }

void z_clock_advance_us(z_clock_t *clock, unsigned long duration) { *clock += (double)(duration / 1000); }

void z_clock_advance_ms(z_clock_t *clock, unsigned long duration) { *clock += (double)duration; }

void z_clock_advance_s(z_clock_t *clock, unsigned long duration) { *clock += (double)(duration * 1000); }

/*------------------ Time ------------------*/
z_time_t z_time_now(void) { return emscripten_get_now(); }
Expand Down
40 changes: 39 additions & 1 deletion src/system/espidf/system.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
// ZettaScale Zenoh Team, <[email protected]>
//

#include <errno.h>
#include <esp_heap_caps.h>
#include <esp_random.h>
#include <stddef.h>
Expand Down Expand Up @@ -142,7 +143,12 @@ z_result_t _z_mutex_try_lock(_z_mutex_t *m) { _Z_CHECK_SYS_ERR(pthread_mutex_try
z_result_t _z_mutex_unlock(_z_mutex_t *m) { _Z_CHECK_SYS_ERR(pthread_mutex_unlock(m)); }

/*------------------ Condvar ------------------*/
z_result_t _z_condvar_init(_z_condvar_t *cv) { _Z_CHECK_SYS_ERR(pthread_cond_init(cv, NULL)); }
z_result_t _z_condvar_init(_z_condvar_t *cv) {
pthread_condattr_t attr;
pthread_condattr_init(&attr);
pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
_Z_CHECK_SYS_ERR(pthread_cond_init(cv, &attr));
}

z_result_t _z_condvar_drop(_z_condvar_t *cv) { _Z_CHECK_SYS_ERR(pthread_cond_destroy(cv)); }

Expand All @@ -151,6 +157,16 @@ z_result_t _z_condvar_signal(_z_condvar_t *cv) { _Z_CHECK_SYS_ERR(pthread_cond_s
z_result_t _z_condvar_signal_all(_z_condvar_t *cv) { _Z_CHECK_SYS_ERR(pthread_cond_broadcast(cv)); }

z_result_t _z_condvar_wait(_z_condvar_t *cv, _z_mutex_t *m) { _Z_CHECK_SYS_ERR(pthread_cond_wait(cv, m)); }

z_result_t _z_condvar_wait_until(_z_condvar_t *cv, _z_mutex_t *m, const z_clock_t *abstime) {
int error = pthread_cond_timedwait(cv, m, abstime);

if (error == ETIMEDOUT) {
return Z_ETIMEDOUT;
}

_Z_CHECK_SYS_ERR(error);
}
#endif // Z_FEATURE_MULTI_THREAD == 1

/*------------------ Sleep ------------------*/
Expand Down Expand Up @@ -202,6 +218,28 @@ unsigned long z_clock_elapsed_s(z_clock_t *instant) {
return elapsed;
}

void z_clock_advance_us(z_clock_t *clock, unsigned long duration) {
clock->tv_sec += duration / 1000000;
clock->tv_nsec += (duration % 1000000) * 1000;

if (clock->tv_nsec >= 1000000000) {
clock->tv_sec += 1;
clock->tv_nsec -= 1000000000;
}
}

void z_clock_advance_ms(z_clock_t *clock, unsigned long duration) {
clock->tv_sec += duration / 1000;
clock->tv_nsec += (duration % 1000) * 1000000;

if (clock->tv_nsec >= 1000000000) {
clock->tv_sec += 1;
clock->tv_nsec -= 1000000000;
}
}

void z_clock_advance_s(z_clock_t *clock, unsigned long duration) { clock->tv_sec += duration; }

/*------------------ Time ------------------*/
z_time_t z_time_now(void) {
z_time_t now;
Expand Down
24 changes: 24 additions & 0 deletions src/system/flipper/system.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ z_result_t _z_condvar_signal_all(_z_condvar_t* cv) { return -1; }

z_result_t _z_condvar_wait(_z_condvar_t* cv, _z_mutex_t* m) { return -1; }

z_result_t _z_condvar_wait_until(_z_condvar_t* cv, _z_mutex_t* m, const z_clock_t* abstime) { return -1; }

/*------------------ Sleep ------------------*/
z_result_t z_sleep_us(size_t time) {
furi_delay_us(time);
Expand Down Expand Up @@ -214,6 +216,28 @@ unsigned long z_clock_elapsed_s(z_clock_t* instant) {
return elapsed;
}

void z_clock_advance_us(z_clock_t* clock, unsigned long duration) {
clock->tv_sec += duration / 1000000;
clock->tv_nsec += (duration % 1000000) * 1000;

if (clock->tv_nsec >= 1000000000) {
clock->tv_sec += 1;
clock->tv_nsec -= 1000000000;
}
}

void z_clock_advance_ms(z_clock_t* clock, unsigned long duration) {
clock->tv_sec += duration / 1000;
clock->tv_nsec += (duration % 1000) * 1000000;

if (clock->tv_nsec >= 1000000000) {
clock->tv_sec += 1;
clock->tv_nsec -= 1000000000;
}
}

void z_clock_advance_s(z_clock_t* clock, unsigned long duration) { clock->tv_sec += duration; }

/*------------------ Time ------------------*/
z_time_t z_time_now(void) {
z_time_t now;
Expand Down
Loading
Loading