blob: 109e70a0d1f80ad43666aaf9f4fb3abce855a17f [file] [log] [blame]
/*
* Copyright (c) 2018 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <pthread.h>
#include <errno.h>
/**
* @brief Destroy semaphore.
*
* FIXME: EBUSY is not taken care as of now
*
* see IEEE 1003.1
*/
int sem_destroy(sem_t *semaphore)
{
if (semaphore == NULL) {
errno = EINVAL;
return -1;
}
k_sem_reset(semaphore);
return 0;
}
/**
* @brief Get value of semaphore.
*
* See IEEE 1003.1
*/
int sem_getvalue(sem_t *semaphore, int *value)
{
*value = (int) k_sem_count_get(semaphore);
return 0;
}
/**
* @brief Initialize semaphore.
*
* API only accepts 0 to share share semaphore among threads. Values
* greater than 0 are invalid as zephyr does not support processes.
*
* See IEEE 1003.1
*/
int sem_init(sem_t *semaphore, int pshared, unsigned int value)
{
if (value > CONFIG_SEM_VALUE_MAX) {
errno = EINVAL;
return -1;
}
if (pshared != 0) {
errno = ENOSYS;
return -1;
}
k_sem_init(semaphore, value, CONFIG_SEM_VALUE_MAX);
return 0;
}
/**
* @brief Unlock a semaphore.
*
* See IEEE 1003.1
*/
int sem_post(sem_t *semaphore)
{
if (semaphore == NULL) {
errno = EINVAL;
return -1;
}
k_sem_give(semaphore);
return 0;
}
static int take_and_convert(sem_t *semaphore, s32_t timeout)
{
int temp, ret;
temp = k_sem_take(semaphore, timeout);
if (temp == -EBUSY) {
errno = EAGAIN;
ret = -1;
} else if (temp != 0) {
errno = ETIMEDOUT;
ret = -1;
} else {
ret = 0;
}
return ret;
}
/**
* @brief Lock a sempahore.
*
* See IEEE 1003.1
*/
int sem_timedwait(sem_t *semaphore, struct timespec *abstime)
{
u32_t timeout;
long msecs = 0;
s64_t current_ms;
s32_t abstime_ms;
__ASSERT(abstime, "abstime pointer NULL");
if ((abstime->tv_sec < 0) || (abstime->tv_nsec >= NSEC_PER_SEC)) {
errno = EINVAL;
return -1;
}
current_ms = k_uptime_get();
abstime_ms = _ts_to_ms(abstime);
msecs = abstime_ms - current_ms;
if (abstime_ms <= current_ms) {
timeout = 0;
} else {
timeout = _ms_to_ticks(msecs);
}
return take_and_convert(semaphore, timeout);
}
/**
* @brief Lock a sempahore.
*
* See IEEE 1003.1
*/
int sem_trywait(sem_t *semaphore)
{
if (k_sem_take(semaphore, K_NO_WAIT) == -EBUSY) {
errno = EAGAIN;
return -1;
} else {
return 0;
}
}
/**
* @brief Lock a sempahore.
*
* See IEEE 1003.1
*/
int sem_wait(sem_t *semaphore)
{
if (k_sem_take(semaphore, K_FOREVER) == -EBUSY) {
errno = EAGAIN;
return -1;
} else {
return 0;
}
}