yb_arm/osp/src/ospSem.c

352 lines
6.9 KiB
C
Raw Normal View History

2023-07-12 14:14:31 +08:00
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "osp.h"
void *osp_semm_create(void)
{
lx_sem_t *sem = (lx_sem_t *)malloc(sizeof(lx_sem_t));
if (sem != NULL)
{
if (pthread_mutex_init(&sem->u.sem_mutex, NULL) == 0)
{
sem->sem_type = SEM_TYPE_MUTEX;
}
else
{
free(sem);
sem = NULL;
}
}
return (void *)sem;
}
void*osp_semsm_create(void *semId)
{
pthread_mutexattr_t mutexAttr;
int32_t Ret;
lx_sem_t *sem;
sem = (lx_sem_t *)semId;
Ret = pthread_mutexattr_init(&mutexAttr);
if (0 != Ret)
{
return NULL;
}
Ret = pthread_mutexattr_setpshared(&mutexAttr, PTHREAD_PROCESS_SHARED);
if (0 != Ret)
{
return NULL;
}
Ret = pthread_mutexattr_setrobust(&mutexAttr, PTHREAD_MUTEX_ROBUST);
if (0 != Ret)
{
return NULL;
}
Ret = pthread_mutex_init(&(sem->u.sem_mutex), &mutexAttr);
if (0 != Ret)
{
osp_debug_out(ERR_DEBUG_LEVEL, "pthread_mutex_init err\n");
return NULL;
}
sem->sem_type = SEM_TYPE_MUTEX;
return (void *)sem;
}
void *osp_semss_create(void *semId)
{
lx_sem_t *sem = (lx_sem_t *)semId;
if (sem_init(&sem->u.sem_count, 1, 0) == 0)
{
sem->sem_type = SEM_TYPE_COUNT;
}
return (void *)sem;
}
void *osp_semb_create(SEM_B_STATE initalState)
{
int32_t initCount = (initalState == SEM_FULL) ? 1 : 0;
lx_sem_t*sem = (lx_sem_t *)malloc(sizeof(lx_sem_t));
if (sem != NULL)
{
if (sem_init(&sem->u.sem_count, 0, initCount) == 0)
{
sem->sem_type = SEM_TYPE_BINARY;
}
else
{
free(sem);
sem = NULL;
}
}
return (void *)sem;
}
void *osp_semc_create(int32_t initCount)
{
lx_sem_t *sem = (lx_sem_t *)malloc(sizeof(lx_sem_t));
if (sem != NULL)
{
if (sem_init(&sem->u.sem_count, 1, initCount) == 0)
{
sem->sem_type = SEM_TYPE_COUNT;
}
else
{
free(sem);
sem = NULL;
}
}
return (void *)sem;
}
int32_t osp_sem_timed_wait_millsecs(lx_sem_t *sem, long msecs)
{
struct timespec ts;
int32_t ret = OSP_OK;
clock_gettime(CLOCK_REALTIME, &ts);
long secs = msecs/1000;
msecs = msecs%1000;
long add = 0;
msecs = msecs*1000*1000 + ts.tv_nsec;
add = msecs / (1000*1000*1000);
ts.tv_sec += (add + secs);
ts.tv_nsec = msecs%(1000*1000*1000);
if (sem->sem_type == SEM_TYPE_MUTEX)
{
ret = pthread_mutex_timedlock(&sem->u.sem_mutex, &ts);
}
else
{
ret = sem_timedwait(&sem->u.sem_count, &ts);
}
return ret;
}
int32_t osp_sem_timedwait_microsecond(lx_sem_t *sem, long msecs)
{
struct timespec ts;
int32_t ret = OSP_OK;
clock_gettime(CLOCK_REALTIME, &ts);
long secs = msecs / 1000000;
msecs = msecs % 1000000;
long add = 0;
msecs = msecs * 1000 + ts.tv_nsec;
add = msecs / (1000 * 1000 * 1000);
ts.tv_sec += (add + secs);
ts.tv_nsec = msecs % (1000 * 1000 * 1000);
if (sem->sem_type == SEM_TYPE_MUTEX)
{
ret = pthread_mutex_timedlock(&sem->u.sem_mutex, &ts);
}
else
{
ret = sem_timedwait(&sem->u.sem_count, &ts);
}
return ret;
}
OSP_STATUS osp_sem_take(void *semId, int32_t timeout)
{
int32_t ret = -1;
lx_sem_t *sem = (lx_sem_t *)semId;
int32_t err = EINTR;
/*errno ==EINTR means this is broken by singnal */
while ((-1 == ret) && (err == EINTR))
{
if (timeout > 0)
{
// ret = osp_sem_timed_wait_millsecs(sem, timeout);
ret = osp_sem_timedwait_microsecond(sem, timeout);
}
else
{
if (sem->sem_type == SEM_TYPE_MUTEX)
ret = pthread_mutex_lock(&sem->u.sem_mutex);
else
ret = sem_wait(&sem->u.sem_count);
}
if (0 != ret)
err = errno;
}
return (OSP_OK);
}
OSP_STATUS osp_sem_taketry(void *semId)
{
int32_t ret;
lx_sem_t *sem = (lx_sem_t *)semId;
if (sem->sem_type == SEM_TYPE_MUTEX)
ret = pthread_mutex_trylock(&sem->u.sem_mutex);
else
ret = sem_trywait(&sem->u.sem_count);
if (ret != 0)
return (OSP_ERROR);
return (OSP_OK);
}
OSP_STATUS osp_sem_give(void *semId)
{
int32_t ret;
lx_sem_t *sem = (lx_sem_t *)semId;
if (sem->sem_type == SEM_TYPE_MUTEX)
ret = pthread_mutex_unlock(&sem->u.sem_mutex);
else if (sem->sem_type == SEM_TYPE_COUNT)
ret = sem_post(&sem->u.sem_count);
else
{
sem_getvalue(&sem->u.sem_count, &ret);
if (ret == 0)
ret = sem_post(&sem->u.sem_count);
}
if (ret != 0)
return (OSP_ERROR);
return (OSP_OK);
}
OSP_STATUS osp_sem_delete(void *semId)
{
int32_t ret;
lx_sem_t *sem = (lx_sem_t *)semId;
if (sem->sem_type == SEM_TYPE_MUTEX)
{
ret = pthread_mutex_destroy(&sem->u.sem_mutex);
}
else
{
ret = sem_destroy(&sem->u.sem_count);
}
free(sem);
return ret;
}
void *osp_semrwc_reate(int32_t readerNum)
{
pthread_rwlock_t *sem = (pthread_rwlock_t *)malloc(sizeof(pthread_rwlock_t));
if (sem != NULL)
{
if (0 != pthread_rwlock_init(sem, NULL))
{
free(sem);
sem = NULL;
}
}
return (void *)sem;
}
OSP_STATUS osp_semr_take(void *semId, int32_t timeout)
{
int32_t ret;
struct timespec timeout1;
pthread_rwlock_t *sem = (pthread_rwlock_t *)semId;
if (timeout > 0)
{
//timeout1.tv_sec = timeout/1000;
//timeout1.tv_nsec = (timeout%1000)*1000000;
clock_gettime(CLOCK_REALTIME, &timeout1);
timeout1.tv_sec += timeout/1000;
timeout1.tv_nsec += (timeout%1000)*1000000;
ret = pthread_rwlock_timedrdlock(sem, &timeout1);
}
else
ret = pthread_rwlock_rdlock(sem);
if (ret != 0)
{
return (OSP_ERROR);
}
return (OSP_OK);
}
OSP_STATUS osp_sem_wtake(void *semId, int32_t timeout)
{
int32_t ret;
struct timespec timeout1;
pthread_rwlock_t *sem = (pthread_rwlock_t *)semId;
if (timeout > 0)
{
//timeout1.tv_sec = timeout/1000;
//timeout1.tv_nsec = (timeout%1000)*1000000;
clock_gettime(CLOCK_REALTIME, &timeout1);
timeout1.tv_sec += timeout/1000;
timeout1.tv_nsec += (timeout%1000)*1000000;
ret = pthread_rwlock_timedwrlock(sem, &timeout1);
}
else
ret = pthread_rwlock_wrlock(sem);
if (ret != 0)
{
return (OSP_ERROR);
}
return (OSP_OK);
}
OSP_STATUS osp_semrw_give(void *semId)
{
int32_t ret;
pthread_rwlock_t *sem = (pthread_rwlock_t *)semId;
ret = pthread_rwlock_unlock(sem);
if (ret != 0)
{
return (OSP_ERROR);
}
return (OSP_OK);
}