1 /*
2 * Copyright (C) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "hc_condition.h"
17
18 #include "hc_log.h"
19
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23
Wait(pthread_cond_t * cond,HcMutex * mutex)24 int Wait(pthread_cond_t* cond, HcMutex* mutex)
25 {
26 if (cond == NULL || mutex == NULL) {
27 return -1;
28 }
29 int res = pthread_cond_wait(cond, &mutex->mutex);
30 if (res != 0) {
31 LOGE("[OS]: pthread_cond_wait fail. [Res]: %d", res);
32 }
33 return res;
34 }
35
Notify(pthread_cond_t * cond)36 void Notify(pthread_cond_t* cond)
37 {
38 if (cond == NULL) {
39 return;
40 }
41 int res = pthread_cond_signal(cond);
42 if (res != 0) {
43 LOGW("[OS]: pthread_cond_wait fail. [Res]: %d", res);
44 }
45 }
46
HcCondWaitWithoutLock(struct HcConditionT * hcCond)47 int HcCondWaitWithoutLock(struct HcConditionT* hcCond)
48 {
49 if (hcCond == NULL || hcCond->mutex == NULL) {
50 return -1;
51 }
52 if (hcCond->notified) {
53 hcCond->notified = HC_FALSE;
54 return 0;
55 } else {
56 int ret;
57 hcCond->waited = HC_TRUE;
58 ret = Wait(&hcCond->cond, hcCond->mutex);
59 hcCond->waited = HC_FALSE;
60 hcCond->notified = HC_FALSE;
61 return ret;
62 }
63 }
64
HcCondNotifyWithoutLock(struct HcConditionT * hcCond)65 void HcCondNotifyWithoutLock(struct HcConditionT* hcCond)
66 {
67 if (hcCond == NULL || hcCond->mutex == NULL) {
68 return;
69 }
70
71 if (!hcCond->waited) {
72 hcCond->notified = HC_TRUE;
73 } else {
74 hcCond->notified = HC_FALSE;
75 }
76 Notify(&hcCond->cond);
77 }
78
HcCondWait(struct HcConditionT * hcCond)79 int HcCondWait(struct HcConditionT* hcCond)
80 {
81 if (hcCond == NULL) {
82 return -1;
83 }
84 if (hcCond->mutex == NULL) {
85 return -1;
86 }
87
88 hcCond->mutex->lock(hcCond->mutex);
89 if (hcCond->notified) {
90 hcCond->notified = HC_FALSE;
91 hcCond->mutex->unlock(hcCond->mutex);
92 return 0;
93 } else {
94 int ret;
95 hcCond->waited = HC_TRUE;
96 ret = Wait(&hcCond->cond, hcCond->mutex);
97 hcCond->waited = HC_FALSE;
98 hcCond->notified = HC_FALSE;
99 hcCond->mutex->unlock(hcCond->mutex);
100 return ret;
101 }
102 }
103
HcCondNotify(struct HcConditionT * hcCond)104 void HcCondNotify(struct HcConditionT* hcCond)
105 {
106 if (hcCond == NULL || hcCond->mutex == NULL) {
107 return;
108 }
109
110 hcCond->mutex->lock(hcCond->mutex);
111
112 if (!hcCond->waited) {
113 hcCond->notified = HC_TRUE;
114 } else {
115 hcCond->notified = HC_FALSE;
116 }
117 Notify(&hcCond->cond);
118 hcCond->mutex->unlock(hcCond->mutex);
119 }
120
InitHcCond(HcCondition * hcCond,HcMutex * mutex)121 int32_t InitHcCond(HcCondition* hcCond, HcMutex* mutex)
122 {
123 if (hcCond == NULL) {
124 return -1;
125 }
126 hcCond->notified = HC_FALSE;
127 hcCond->waited = HC_FALSE;
128 hcCond->wait = HcCondWait;
129 hcCond->notify = HcCondNotify;
130 hcCond->waitWithoutLock = HcCondWaitWithoutLock;
131 hcCond->notifyWithoutLock = HcCondNotifyWithoutLock;
132
133 pthread_condattr_t attr;
134 pthread_condattr_init(&attr);
135 int res = pthread_cond_init(&hcCond->cond, &attr);
136 pthread_condattr_destroy(&attr);
137 if (res != 0) {
138 LOGE("[OS]: pthread_cond_init fail. [Res]: %d", res);
139 return -1;
140 }
141
142 if (mutex != NULL) {
143 hcCond->mutex = mutex;
144 hcCond->innerMutex = HC_FALSE;
145 } else {
146 hcCond->mutex = (HcMutex*)HcMalloc(sizeof(HcMutex), 0);
147 if (hcCond->mutex != NULL) {
148 res = InitHcMutex(hcCond->mutex);
149 if (res != 0) {
150 HcFree(hcCond->mutex);
151 hcCond->mutex = NULL;
152 return res;
153 }
154 hcCond->innerMutex = HC_TRUE;
155 } else {
156 return -1;
157 }
158 }
159 return 0;
160 }
161
DestroyHcCond(HcCondition * hcCond)162 void DestroyHcCond(HcCondition* hcCond)
163 {
164 if (hcCond == NULL) {
165 return;
166 }
167
168 if (hcCond->innerMutex && hcCond->mutex) {
169 DestroyHcMutex(hcCond->mutex);
170 HcFree(hcCond->mutex);
171 hcCond->mutex = NULL;
172 }
173 int res = pthread_cond_destroy(&hcCond->cond);
174 if (res != 0) {
175 LOGW("[OS]: pthread_cond_destroy fail. [Res]: %d", res);
176 }
177 }
178
179 #ifdef __cplusplus
180 }
181 #endif