Skip to content

Commit

Permalink
Add sem_drain_and_wait_timeout and time_to_ticks to lispBM.
Browse files Browse the repository at this point in the history
The new `sem_drain_and_wait_timeout` effectively achieves binary
semaphore semantics without relying on `ch_binary_semaphore`.

`time_to_ticks` is necessary to pass the correct timeout values to
`sem_wait_to` and `sem_drain_and_wait_timeout`
  • Loading branch information
lolwheel committed Jul 16, 2024
1 parent 68094e9 commit c3798ee
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 1 deletion.
6 changes: 5 additions & 1 deletion lispBM/c_libs/vesc_c_if.h
Original file line number Diff line number Diff line change
Expand Up @@ -650,12 +650,16 @@ typedef struct {
const float* (*foc_get_audio_sample_table)(int channel);
bool (*foc_play_audio_samples)(const int8_t *samples, int num_samp, float f_samp, float voltage);

// Semaphore
// Semaphores
lib_semaphore (*sem_create)(void); // Use VESC_IF->free on the semaphore when done with it
void (*sem_wait)(lib_semaphore);
void (*sem_signal)(lib_semaphore);
bool (*sem_wait_to)(lib_semaphore, systime_t); // Returns false on timeout
void (*sem_reset)(lib_semaphore);
int32_t (*sem_drain_and_wait_timeout)(lib_semaphore, systime_t);

// Os continued
systime_t (*time_to_ticks)(uint32_t seconds, uint32_t millis, uint32_t micros);
} vesc_c_if;

typedef struct {
Expand Down
31 changes: 31 additions & 0 deletions lispBM/lispif_c_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,33 @@ static void lib_sem_reset(lib_semaphore s) {
chSemReset((semaphore_t*)s, 0);
}

// Guaranteed to block. First drains the semaphore to 0 if its counter is positive and
// then waits on it with given timeout(special values TIME_IMMEDIATE and TIME_INFINITE are honored).
// Returns MSG_RESET or MSG_TIMEOUT if that was the result of the wait operations.
// Otherwise returns a non-negative number of overruns, i.e. the number by which the semaphore
// had to be decreased before the wait operation.
//
// Useful for implementing binary-semaphore like semantics where it's important to ignore
// semaphore overruns.
static int32_t lib_sem_drain_and_wait_timeout(lib_semaphore sem, systime_t timeout) {
chSysLock();
const cnt_t sem_counter = chSemGetCounterI((semaphore_t*)sem);
// setCounter isn't exposed and I don't want to manually manipulate the internal counter
for (cnt_t i = 0; i < sem_counter; i++) {
chSemFastWaitI((semaphore_t*)sem);
}
const msg_t wait_result = chSemWaitTimeoutS((semaphore_t*)sem, timeout);
chSysUnlock();
if (wait_result < 0) { // MSG_RESET and MSG_TIMEOUT are negative
return wait_result;
}
return sem_counter < 0 ? 0 : sem_counter;
}

static systime_t lib_time_to_ticks(uint32_t seconds, uint32_t millis, uint32_t micros) {
return S2ST(seconds) + MS2ST(millis) + US2ST(micros);
}

static remote_state lib_get_remote_state(void) {
remote_state res;
res.js_x = app_nunchuk_get_decoded_x();
Expand Down Expand Up @@ -1022,6 +1049,10 @@ lbm_value ext_load_native_lib(lbm_value *args, lbm_uint argn) {
cif.cif.sem_signal = lib_sem_signal;
cif.cif.sem_wait_to = lib_sem_wait_to;
cif.cif.sem_reset = lib_sem_reset;
cif.cif.sem_drain_and_wait_timeout = lib_sem_drain_and_wait_timeout;

// OS continued
cif.cif.time_to_ticks = lib_time_to_ticks;

lib_init_done = true;
}
Expand Down

0 comments on commit c3798ee

Please sign in to comment.