1 /*
2 * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include "osal_mutex.h"
10 #include <pthread.h>
11 #include "securec.h"
12 #include "hdf_log.h"
13 #include "osal_mem.h"
14
15 #define HDF_LOG_TAG osal_mutex
16 #define HDF_NANO_UNITS 1000000000
17
OsalMutexInit(struct OsalMutex * mutex)18 int32_t OsalMutexInit(struct OsalMutex *mutex)
19 {
20 pthread_mutex_t *mutexTmp = NULL;
21 int32_t ret;
22
23 if (mutex == NULL) {
24 HDF_LOGE("%s invalid param", __func__);
25 return HDF_ERR_INVALID_PARAM;
26 }
27
28 mutex->realMutex = NULL;
29
30 mutexTmp = (pthread_mutex_t *)OsalMemCalloc(sizeof(pthread_mutex_t));
31 if (mutexTmp == NULL) {
32 HDF_LOGE("%s malloc fail", __func__);
33 return HDF_ERR_MALLOC_FAIL;
34 }
35
36 ret = pthread_mutex_init(mutexTmp, NULL);
37 if (ret != 0) {
38 HDF_LOGE("%s fail %d %d", __func__, ret, __LINE__);
39 OsalMemFree(mutexTmp);
40 return HDF_FAILURE;
41 }
42
43 mutex->realMutex = (void *)mutexTmp;
44
45 return HDF_SUCCESS;
46 }
47
OsalMutexDestroy(struct OsalMutex * mutex)48 int32_t OsalMutexDestroy(struct OsalMutex *mutex)
49 {
50 int32_t ret;
51
52 if (mutex == NULL || mutex->realMutex == NULL) {
53 HDF_LOGE("%s invalid param", __func__);
54 return HDF_ERR_INVALID_PARAM;
55 }
56
57 ret = pthread_mutex_destroy((pthread_mutex_t *)mutex->realMutex);
58 if (ret != 0) {
59 HDF_LOGE("%s fail %d %d", __func__, ret, __LINE__);
60 return HDF_FAILURE;
61 }
62
63 OsalMemFree(mutex->realMutex);
64 mutex->realMutex = NULL;
65
66 return HDF_SUCCESS;
67 }
68
OsalMutexLock(struct OsalMutex * mutex)69 int32_t OsalMutexLock(struct OsalMutex *mutex)
70 {
71 if (mutex == NULL || mutex->realMutex == NULL) {
72 HDF_LOGE("%s invalid param", __func__);
73 return HDF_ERR_INVALID_PARAM;
74 }
75 return OsalMutexTimedLock(mutex, HDF_WAIT_FOREVER);
76 }
77
OsalMutexTimedLock(struct OsalMutex * mutex,uint32_t ms)78 int32_t OsalMutexTimedLock(struct OsalMutex *mutex, uint32_t ms)
79 {
80 int32_t ret;
81
82 if (mutex == NULL || mutex->realMutex == NULL) {
83 HDF_LOGE("%s invalid param", __func__);
84 return HDF_ERR_INVALID_PARAM;
85 }
86
87 if (ms == HDF_WAIT_FOREVER) {
88 ret = pthread_mutex_lock((pthread_mutex_t *)mutex->realMutex);
89 if (ret != 0) {
90 HDF_LOGE("pthread_mutex_lock fail %d", ret);
91 return HDF_FAILURE;
92 }
93 } else {
94 struct timespec time;
95 (void)memset_s(&time, sizeof(time), 0, sizeof(time));
96 clock_gettime(CLOCK_REALTIME, &time);
97 time.tv_sec += (time_t)ms / HDF_KILO_UNIT;
98 time.tv_nsec += (time_t)(ms % HDF_KILO_UNIT) * HDF_KILO_UNIT * HDF_KILO_UNIT;
99 if (time.tv_nsec >= HDF_NANO_UNITS) {
100 time.tv_nsec -= HDF_NANO_UNITS;
101 time.tv_sec += 1;
102 }
103 ret = pthread_mutex_timedlock((pthread_mutex_t *)mutex->realMutex, &time);
104 if (ret != 0) {
105 if (ret == ETIMEDOUT) {
106 return HDF_ERR_TIMEOUT;
107 } else {
108 HDF_LOGE("%s time_out time:%u ret:%d", __func__, ms, ret);
109 return HDF_FAILURE;
110 }
111 }
112 }
113
114 return HDF_SUCCESS;
115 }
116
OsalMutexUnlock(struct OsalMutex * mutex)117 int32_t OsalMutexUnlock(struct OsalMutex *mutex)
118 {
119 int32_t ret;
120
121 if (mutex == NULL || mutex->realMutex == NULL) {
122 HDF_LOGE("%s invalid param", __func__);
123 return HDF_ERR_INVALID_PARAM;
124 }
125
126 ret = pthread_mutex_unlock((pthread_mutex_t *)mutex->realMutex);
127 if (ret != 0) {
128 HDF_LOGE("%s fail %d %d", __func__, ret, __LINE__);
129 return HDF_FAILURE;
130 }
131
132 return HDF_SUCCESS;
133 }
134
135