kernel: Add posix API for semaphore
Add semaphore posix APIs. Signed-off-by: Punit Vara <punit.vara@intel.com>
This commit is contained in:
parent
b9588d8eb6
commit
a74725f1d3
7 changed files with 210 additions and 1 deletions
|
@ -42,6 +42,7 @@
|
||||||
#define pthread_rwlock_obj zap_pthread_rwlock_obj
|
#define pthread_rwlock_obj zap_pthread_rwlock_obj
|
||||||
#define pthread_rwlockattr_t zap_pthread_rwlockattr_t
|
#define pthread_rwlockattr_t zap_pthread_rwlockattr_t
|
||||||
/* Condition variables */
|
/* Condition variables */
|
||||||
|
|
||||||
#define pthread_cond_init(...) zap_pthread_cond_init(__VA_ARGS__)
|
#define pthread_cond_init(...) zap_pthread_cond_init(__VA_ARGS__)
|
||||||
#define pthread_cond_destroy(...) zap_pthread_cond_destroy(__VA_ARGS__)
|
#define pthread_cond_destroy(...) zap_pthread_cond_destroy(__VA_ARGS__)
|
||||||
#define pthread_cond_signal(...) zap_pthread_cond_signal(__VA_ARGS__)
|
#define pthread_cond_signal(...) zap_pthread_cond_signal(__VA_ARGS__)
|
||||||
|
@ -50,6 +51,16 @@
|
||||||
#define pthread_cond_timedwait(...) zap_pthread_cond_timedwait(__VA_ARGS__)
|
#define pthread_cond_timedwait(...) zap_pthread_cond_timedwait(__VA_ARGS__)
|
||||||
#define pthread_condattr_init(...) zap_pthread_condattr_init(__VA_ARGS__)
|
#define pthread_condattr_init(...) zap_pthread_condattr_init(__VA_ARGS__)
|
||||||
#define pthread_condattr_destroy(...) zap_pthread_condattr_destroy(__VA_ARGS__)
|
#define pthread_condattr_destroy(...) zap_pthread_condattr_destroy(__VA_ARGS__)
|
||||||
|
|
||||||
|
/* Semaphore */
|
||||||
|
#define sem_destroy(...) zap_sem_destroy(__VA_ARGS__)
|
||||||
|
#define sem_getvalue(...) zap_sem_getvalue(__VA_ARGS__)
|
||||||
|
#define sem_init(...) zap_sem_init(__VA_ARGS__)
|
||||||
|
#define sem_post(...) zap_sem_post(__VA_ARGS__)
|
||||||
|
#define sem_timedwait(...) zap_sem_timedwait(__VA_ARGS__)
|
||||||
|
#define sem_trywait(...) zap_sem_trywait(__VA_ARGS__)
|
||||||
|
#define sem_wait(...) zap_sem_wait(__VA_ARGS__)
|
||||||
|
|
||||||
/* Mutex */
|
/* Mutex */
|
||||||
#define pthread_mutex_init(...) zap_pthread_mutex_init(__VA_ARGS__)
|
#define pthread_mutex_init(...) zap_pthread_mutex_init(__VA_ARGS__)
|
||||||
#define pthread_mutex_destroy(...) zap_pthread_mutex_destroy(__VA_ARGS__)
|
#define pthread_mutex_destroy(...) zap_pthread_mutex_destroy(__VA_ARGS__)
|
||||||
|
|
|
@ -157,7 +157,6 @@ static inline int pthread_condattr_destroy(pthread_condattr_t *att)
|
||||||
.sem = &name##_psem, \
|
.sem = &name##_psem, \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief POSIX threading compatibility API
|
* @brief POSIX threading compatibility API
|
||||||
*
|
*
|
||||||
|
|
28
include/posix/semaphore.h
Normal file
28
include/posix/semaphore.h
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018 Intel Corporation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
#ifndef _POSIX_SEMAPHORE_H
|
||||||
|
#define _POSIX_SEMAPHORE_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "sys/types.h"
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
int sem_destroy(sem_t *semaphore);
|
||||||
|
int sem_getvalue(sem_t *semaphore, int *value);
|
||||||
|
int sem_init(sem_t *semaphore, int pshared, unsigned int value);
|
||||||
|
int sem_post(sem_t *semaphore);
|
||||||
|
int sem_timedwait(sem_t *semaphore, struct timespec *abstime);
|
||||||
|
int sem_trywait(sem_t *semaphore);
|
||||||
|
int sem_wait(sem_t *semaphore);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* POSIX_SEMAPHORE_H */
|
|
@ -30,6 +30,9 @@ typedef struct pthread_attr_t {
|
||||||
|
|
||||||
typedef void *pthread_t;
|
typedef void *pthread_t;
|
||||||
|
|
||||||
|
/* Semaphore */
|
||||||
|
typedef struct k_sem sem_t;
|
||||||
|
|
||||||
/* Mutex */
|
/* Mutex */
|
||||||
typedef struct pthread_mutex {
|
typedef struct pthread_mutex {
|
||||||
struct k_sem *sem;
|
struct k_sem *sem;
|
||||||
|
|
|
@ -513,6 +513,14 @@ config MAX_PTHREAD_COUNT
|
||||||
help
|
help
|
||||||
Mention maximum number of threads in POSIX compliant application.
|
Mention maximum number of threads in POSIX compliant application.
|
||||||
|
|
||||||
|
config SEM_VALUE_MAX
|
||||||
|
int
|
||||||
|
prompt "Maximum semaphore limit"
|
||||||
|
default 32767
|
||||||
|
range 1 32767
|
||||||
|
help
|
||||||
|
Maximum semaphore count in POSIX compliant Application.
|
||||||
|
|
||||||
config MAX_TIMER_COUNT
|
config MAX_TIMER_COUNT
|
||||||
int
|
int
|
||||||
prompt "Maximum timer count in POSIX application"
|
prompt "Maximum timer count in POSIX application"
|
||||||
|
|
|
@ -7,3 +7,4 @@ target_sources(kernel PRIVATE posix/pthread_sched.c)
|
||||||
target_sources(kernel PRIVATE posix/clock.c)
|
target_sources(kernel PRIVATE posix/clock.c)
|
||||||
target_sources(kernel PRIVATE posix/timer.c)
|
target_sources(kernel PRIVATE posix/timer.c)
|
||||||
target_sources(kernel PRIVATE posix/pthread_rwlock.c)
|
target_sources(kernel PRIVATE posix/pthread_rwlock.c)
|
||||||
|
target_sources(kernel PRIVATE posix/semaphore.c)
|
||||||
|
|
159
kernel/posix/semaphore.c
Normal file
159
kernel/posix/semaphore.c
Normal file
|
@ -0,0 +1,159 @@
|
||||||
|
/*
|
||||||
|
* 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 == 0 || 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;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue