强化openharmony osal_mutex 互斥锁
·
#include "osal_mutex.h"
#include <pthread.h>
#include <stdatomic.h>
#include "securec.h"
#include "hdf_core_log.h"
#include "osal_mem.h"
#define HDF_LOG_TAG osal_mutex
#define HDF_NANO_UNITS 1000000000
#define HDF_KILO_UNIT 1000
#define HDF_WAIT_FOREVER 0xFFFFFFFF
typedef struct {
pthread_mutex_t mutex;
atomic_int refCount;
} OsalMutexExt;
int32_t OsalMutexInit(struct OsalMutex *mutex)
{
OsalMutexExt *ext = NULL;
int32_t ret;
if (mutex == NULL) {
HDF_LOGE("%s invalid param", __func__);
return HDF_ERR_INVALID_PARAM;
}
mutex->realMutex = NULL;
ext = (OsalMutexExt *)OsalMemCalloc(sizeof(OsalMutexExt));
if (ext == NULL) {
HDF_LOGE("%s malloc fail", __func__);
return HDF_ERR_MALLOC_FAIL;
}
ret = pthread_mutex_init(&ext->mutex, NULL);
if (ret != 0) {
HDF_LOGE("%s: failed to init pthread mutex %d", __func__, ret);
OsalMemFree(ext);
return HDF_FAILURE;
}
atomic_init(&ext->refCount, 0);
mutex->realMutex = (void *)ext;
return HDF_SUCCESS;
}
int32_t OsalMutexDestroy(struct OsalMutex *mutex)
{
int32_t ret = 0;
OsalMutexExt *ext = NULL;
if (mutex == NULL || mutex->realMutex == NULL) {
return HDF_ERR_INVALID_PARAM;
}
ext = (OsalMutexExt *)mutex->realMutex;
ret = pthread_mutex_trylock(&ext->mutex);
if (ret != 0) {
HDF_LOGE("%s: mutex is locked by other thread", __func__);
return HDF_ERR_IO;
}
if (atomic_load(&ext->refCount) != 0) {
HDF_LOGE("%s: refCount is not zero (%d)", __func__, atomic_load(&ext->refCount));
pthread_mutex_unlock(&ext->mutex);
return HDF_ERR_IO;
}
ret = pthread_mutex_destroy(&ext->mutex);
if (ret != 0) {
HDF_LOGE("%s: failed to destroy pthread mutex %d", __func__, ret);
}
OsalMemFree(ext);
mutex->realMutex = NULL;
return HDF_SUCCESS;
}
int32_t OsalMutexLock(struct OsalMutex *mutex)
{
if (mutex == NULL || mutex->realMutex == NULL) {
HDF_LOGE("%s invalid param", __func__);
return HDF_ERR_INVALID_PARAM;
}
return OsalMutexTimedLock(mutex, HDF_WAIT_FOREVER);
}
int32_t OsalMutexTimedLock(struct OsalMutex *mutex, uint32_t ms)
{
int32_t ret;
OsalMutexExt *ext = NULL;
if (mutex == NULL || mutex->realMutex == NULL) {
HDF_LOGE("%s invalid param", __func__);
return HDF_ERR_INVALID_PARAM;
}
ext = (OsalMutexExt *)mutex->realMutex;
if (ms == HDF_WAIT_FOREVER) {
ret = pthread_mutex_lock(&ext->mutex);
if (ret != 0) {
HDF_LOGE("pthread_mutex_lock fail %d", ret);
return HDF_FAILURE;
}
atomic_fetch_add_explicit(&ext->refCount, 1, memory_order_release);
return HDF_SUCCESS;
} 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) * 1000 * 1000;
if (time.tv_nsec >= HDF_NANO_UNITS) {
time.tv_nsec -= HDF_NANO_UNITS;
time.tv_sec += 1;
}
ret = pthread_mutex_timedlock(&ext->mutex, &time);
if (ret == 0) {
atomic_fetch_add_explicit(&ext->refCount, 1, memory_order_release);
return HDF_SUCCESS;
} else if (ret == ETIMEDOUT) {
HDF_LOGD("%s timed out, ms:%u", __func__, ms);
return HDF_ERR_TIMEOUT;
} else {
HDF_LOGE("%s pthread_mutex_timedlock fail, ms:%u ret:%d", __func__, ms, ret);
return HDF_FAILURE;
}
}
}
int32_t OsalMutexUnlock(struct OsalMutex *mutex)
{
int32_t ret;
OsalMutexExt *ext = NULL;
if (mutex == NULL || mutex->realMutex == NULL) {
HDF_LOGE("%s invalid param", __func__);
return HDF_ERR_INVALID_PARAM;
}
ext = (OsalMutexExt *)mutex->realMutex;
if (atomic_load_explicit(&ext->refCount, memory_order_acquire) <= 0) {
HDF_LOGE("%s: unlock unlocked mutex (refCount=%d)", __func__, atomic_load(&ext->refCount));
return HDF_ERR_INVALID_PARAM;
}
ret = pthread_mutex_unlock(&ext->mutex);
if (ret != 0) {
HDF_LOGE("%s failed to pthread unlock %d", __func__, ret);
return ret;
}
atomic_fetch_sub_explicit(&ext->refCount, 1, memory_order_release);
return HDF_SUCCESS;
}
更多推荐

所有评论(0)