* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include "osal_sem.h"
#include <errno.h>
#include <semaphore.h>
#include <time.h>
#include "securec.h"
#include "hdf_log.h"
#include "osal_mem.h"
const int32_t SHARE = 0;
#define HDF_LOG_TAG osal_sem
#define HDF_NANO_UNITS 1000000000
int32_t OsalSemInit(struct OsalSem *sem, uint32_t value)
{
sem_t *semTmp = NULL;
if (sem == NULL) {
HDF_LOGE("%s invalid param", __func__);
return HDF_ERR_INVALID_PARAM;
}
sem->realSemaphore = NULL;
semTmp = (sem_t *)OsalMemCalloc(sizeof(sem_t));
if (semTmp == NULL) {
HDF_LOGE("malloc fail");
return HDF_ERR_MALLOC_FAIL;
}
if (sem_init(semTmp, SHARE, value) != 0) {
HDF_LOGE("sem_init fail errno:%d", errno);
OsalMemFree(semTmp);
return HDF_FAILURE;
}
sem->realSemaphore = (void *)semTmp;
return HDF_SUCCESS;
}
int32_t OsalSemWait(struct OsalSem *sem, uint32_t ms)
{
if (sem == NULL || sem->realSemaphore == NULL) {
HDF_LOGE("%s invalid param", __func__);
return HDF_ERR_INVALID_PARAM;
}
if (ms == HDF_WAIT_FOREVER) {
if (sem_wait((sem_t *)sem->realSemaphore) != 0) {
HDF_LOGE("sem_wait fail errno:%d", errno);
return HDF_FAILURE;
}
} else {
struct timespec time;
(void)memset_s(&time, sizeof(time), 0, sizeof(time));
clock_gettime(CLOCK_REALTIME, &time);
time.tv_sec += (time_t)ms / HDF_KILO_UNIT;
time.tv_nsec += (time_t)(ms % HDF_KILO_UNIT) * HDF_KILO_UNIT * HDF_KILO_UNIT;
if (time.tv_nsec >= HDF_NANO_UNITS) {
time.tv_nsec -= HDF_NANO_UNITS;
time.tv_sec += 1;
}
int32_t ret = sem_timedwait((sem_t *)sem->realSemaphore, &time);
if (ret != 0) {
if (errno == ETIMEDOUT) {
return HDF_ERR_TIMEOUT;
} else {
HDF_LOGE("%s time_out time:%d ret:%d,errno:%d", __func__, ms, ret, errno);
return HDF_FAILURE;
}
}
}
return HDF_SUCCESS;
}
int32_t OsalSemPost(struct OsalSem *sem)
{
if (sem == NULL || sem->realSemaphore == NULL) {
HDF_LOGE("%s invalid param", __func__);
return HDF_ERR_INVALID_PARAM;
}
if (sem_post((sem_t *)sem->realSemaphore) != 0) {
HDF_LOGE("sem_post fail errno:%d", errno);
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
int32_t OsalSemDestroy(struct OsalSem *sem)
{
if (sem == NULL || sem->realSemaphore == NULL) {
HDF_LOGE("%s invalid param", __func__);
return HDF_ERR_INVALID_PARAM;
}
int32_t ret = sem_destroy((sem_t *)sem->realSemaphore);
if (ret != 0) {
HDF_LOGE("sem_destroy fail errno:%d", errno);
return HDF_FAILURE;
}
OsalMemFree(sem->realSemaphore);
sem->realSemaphore = NULL;
return HDF_SUCCESS;
}