#include #include #include #include #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); }