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