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

Add a signals API #567

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
13 changes: 13 additions & 0 deletions include/golioth/golioth_sys.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,19 @@ bool golioth_sys_sem_give(golioth_sys_sem_t sem);
void golioth_sys_sem_destroy(golioth_sys_sem_t sem);
int golioth_sys_sem_get_fd(golioth_sys_sem_t sem);

/*--------------------------------------------------
* Signals
*------------------------------------------------*/

// Opaque handle for signal
typedef void *golioth_sys_signal_t;

golioth_sys_signal_t golioth_sys_signal_create(void);
bool golioth_sys_signal_poll(golioth_sys_signal_t sig, int32_t ms_to_wait);
bool golioth_sys_signal_raise(golioth_sys_signal_t sig);
void golioth_sys_signal_reset(golioth_sys_signal_t sig);
void golioth_sys_signal_destroy(golioth_sys_signal_t sig);

/*--------------------------------------------------
* Software Timers
*------------------------------------------------*/
Expand Down
53 changes: 53 additions & 0 deletions port/freertos/golioth_sys_freertos.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,59 @@ int golioth_sys_sem_get_fd(golioth_sys_sem_t sem)
return -1;
}

/*--------------------------------------------------
* Signals
*------------------------------------------------*/

golioth_sys_signal_t golioth_sys_signal_create(void)
{
return xTaskGetCurrentTaskHandle();
}

bool golioth_sys_signal_poll(golioth_sys_signal_t sig, int32_t ms_to_wait)
{
if (!sig)
{
return false;
}

TickType_t ticks_to_wait = (ms_to_wait < 0 ? portMAX_DELAY : pdMS_TO_TICKS(ms_to_wait));

return (pdPASS == ulTaskNotifyTake(pdTRUE, ticks_to_wait));
}

bool golioth_sys_signal_raise(golioth_sys_signal_t sig)
{
if (!sig)
{
return false;
}

BaseType_t xHigherPriorityTaskWoken = pdFALSE;

vTaskNotifyGiveFromISR((TaskHandle_t) sig, &xHigherPriorityTaskWoken);

portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
return true;
}

void golioth_sys_signal_reset(golioth_sys_signal_t sig)
{
if (!sig)
{
return;
}

xTaskNotifyStateClear((TaskHandle_t) sig);
}

void golioth_sys_signal_destroy(golioth_sys_signal_t sig)
{
/* We didn't allocate any memory for TaskHandle_t */
(void) sig;
return;
}

/*--------------------------------------------------
* Software Timers
*------------------------------------------------*/
Expand Down
77 changes: 77 additions & 0 deletions port/linux/golioth_sys_linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,83 @@ int golioth_sys_sem_get_fd(golioth_sys_sem_t sem)
return SEM_TO_FD(sem);
}

/*--------------------------------------------------
* Signals
*------------------------------------------------*/

struct condition_and_mutex
{
pthread_cond_t cond;
pthread_mutex_t lock;
};

golioth_sys_signal_t golioth_sys_signal_create(void)
{
struct condition_and_mutex *sig = golioth_sys_malloc(sizeof(struct condition_and_mutex));
pthread_cond_init(&sig->cond, NULL);
pthread_mutex_init(&sig->lock, NULL);
return (golioth_sys_signal_t) sig;
}

bool golioth_sys_signal_poll(golioth_sys_signal_t sig, int32_t ms_to_wait)
{
if (!sig)
{
return false;
}

int ret = 0;
struct condition_and_mutex *signal = sig;
struct timespec abstime;

pthread_mutex_lock(&signal->lock);

if (ms_to_wait < 0)
{
ret = (0 == pthread_cond_wait(&signal->cond, &signal->lock));
goto signal_poll_finish;
}

clock_gettime(CLOCK_REALTIME, &abstime);

if (ms_to_wait)
{
abstime.tv_sec += ms_to_wait / 1000;
abstime.tv_nsec += (ms_to_wait % 1000) * 1000000;
}

ret = (0 == pthread_cond_timedwait(&signal->cond, &signal->lock, &abstime));

signal_poll_finish:
pthread_mutex_unlock(&signal->lock);
return ret;
}

bool golioth_sys_signal_raise(golioth_sys_signal_t sig)
{
if (!sig)
{
return false;
}

struct condition_and_mutex *signal = sig;
return (0 == pthread_cond_signal(&signal->cond));
}

void golioth_sys_signal_reset(golioth_sys_signal_t sig)
{
/* There is nothing to reset */
return;
}

void golioth_sys_signal_destroy(golioth_sys_signal_t sig)
{
struct condition_and_mutex *signal = sig;
pthread_cond_destroy(&signal->cond);
pthread_mutex_destroy(&signal->lock);
golioth_sys_free(sig);
}

/*--------------------------------------------------
* Software Timers
*------------------------------------------------*/
Expand Down
52 changes: 52 additions & 0 deletions port/zephyr/golioth_sys_zephyr.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,58 @@ int golioth_sys_sem_get_fd(golioth_sys_sem_t sem)
return SEM_TO_FD(sem);
}

/*--------------------------------------------------
* Signals
*------------------------------------------------*/

golioth_sys_signal_t golioth_sys_signal_create(void)
{
struct k_poll_signal *sig = golioth_sys_malloc(sizeof(struct k_poll_signal));
k_poll_signal_init(sig);
return sig;
}

bool golioth_sys_signal_poll(golioth_sys_signal_t sig, int32_t ms_to_wait)
{
if (!sig)
{
return false;
}

k_timeout_t timeout = (ms_to_wait <= GOLIOTH_SYS_WAIT_FOREVER ? K_FOREVER : K_MSEC(ms_to_wait));

struct k_poll_event events[1] = {
K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_SIGNAL, K_POLL_MODE_NOTIFY_ONLY, sig),
};

k_poll(events, 1, timeout);

int signaled, result;
k_poll_signal_check(sig, &signaled, &result);

return (signaled != 0 ? true : false);
}

bool golioth_sys_signal_raise(golioth_sys_signal_t sig)
{
return (0 == k_poll_signal_raise(sig, 0));
}

void golioth_sys_signal_reset(golioth_sys_signal_t sig)
{
if (!sig)
{
return;
}

k_poll_signal_reset(sig);
}

void golioth_sys_signal_destroy(golioth_sys_signal_t sig)
{
golioth_sys_free(sig);
}

/*--------------------------------------------------
* Software Timers
*------------------------------------------------*/
Expand Down
Loading