001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020 #include <hwcore/irq.h>
021 #include <sos/assert.h>
022
023
024 #include "ksynch.h"
025
026
027 sos_ret_t sos_ksema_init(struct sos_ksema *sema, const char *name,
028 int initial_value,
029 sos_kwaitq_ordering_t ordering)
030 {
031 sema->value = initial_value;
032 return sos_kwaitq_init(& sema->kwaitq, name, ordering);
033 }
034
035
036 sos_ret_t sos_ksema_dispose(struct sos_ksema *sema)
037 {
038 return sos_kwaitq_dispose(& sema->kwaitq);
039 }
040
041
042 sos_ret_t sos_ksema_down(struct sos_ksema *sema,
043 struct sos_time *timeout)
044 {
045 sos_ui32_t flags;
046 sos_ret_t retval;
047
048 sos_disable_IRQs(flags);
049 retval = SOS_OK;
050
051 sema->value --;
052 if (sema->value < 0)
053 {
054
055 retval = sos_kwaitq_wait(& sema->kwaitq, timeout);
056
057
058 if (SOS_OK != retval)
059 {
060
061 sema->value ++;
062 }
063 }
064
065 sos_restore_IRQs(flags);
066 return retval;
067 }
068
069
070 sos_ret_t sos_ksema_trydown(struct sos_ksema *sema)
071 {
072 sos_ui32_t flags;
073 sos_ret_t retval;
074
075 sos_disable_IRQs(flags);
076
077
078 if (sema->value >= 1)
079 {
080
081 sema->value --;
082 retval = SOS_OK;
083 }
084 else
085 {
086
087 retval = -SOS_EBUSY;
088 }
089
090 sos_restore_IRQs(flags);
091 return retval;
092 }
093
094
095 sos_ret_t sos_ksema_up(struct sos_ksema *sema)
096 {
097 sos_ui32_t flags;
098 sos_ret_t retval;
099
100 sos_disable_IRQs(flags);
101
102 sema->value ++;
103 retval = sos_kwaitq_wakeup(& sema->kwaitq, 1, SOS_OK);
104
105 sos_restore_IRQs(flags);
106 return retval;
107 }
108
109
110 sos_ret_t sos_kmutex_init(struct sos_kmutex *mutex, const char *name,
111 sos_kwaitq_ordering_t ordering)
112 {
113 mutex->owner = NULL;
114 return sos_kwaitq_init(& mutex->kwaitq, name, ordering);
115 }
116
117
118 sos_ret_t sos_kmutex_dispose(struct sos_kmutex *mutex)
119 {
120 return sos_kwaitq_dispose(& mutex->kwaitq);
121 }
122
123
124
125
126
127
128
129
130
131
132
133 sos_ret_t sos_kmutex_lock(struct sos_kmutex *mutex,
134 struct sos_time *timeout)
135 {
136 __label__ exit_kmutex_lock;
137 sos_ui32_t flags;
138 sos_ret_t retval;
139
140 sos_disable_IRQs(flags);
141 retval = SOS_OK;
142
143
144 if (NULL != mutex->owner)
145 {
146
147 if (sos_thread_get_current() == mutex->owner)
148 {
149
150 retval = -SOS_EBUSY;
151 goto exit_kmutex_lock;
152 }
153
154
155 retval = sos_kwaitq_wait(& mutex->kwaitq, timeout);
156
157
158 if (SOS_OK != retval)
159 {
160 goto exit_kmutex_lock;
161 }
162 }
163
164
165 mutex->owner = sos_thread_get_current();
166
167 exit_kmutex_lock:
168 sos_restore_IRQs(flags);
169 return retval;
170 }
171
172
173 sos_bool_t sos_kmutex_owned_by_me(struct sos_kmutex const* mutex)
174 {
175 sos_ui32_t flags;
176 sos_bool_t retval;
177
178 sos_disable_IRQs(flags);
179 retval = (sos_thread_get_current() == mutex->owner);
180 sos_restore_IRQs(flags);
181
182 return retval;
183 }
184
185
186 sos_ret_t sos_kmutex_trylock(struct sos_kmutex *mutex)
187 {
188 sos_ui32_t flags;
189 sos_ret_t retval;
190
191 sos_disable_IRQs(flags);
192
193
194 if (NULL == mutex->owner)
195 {
196
197 mutex->owner = sos_thread_get_current();
198
199 retval = SOS_OK;
200 }
201 else
202 {
203
204 retval = -SOS_EBUSY;
205 }
206
207 sos_restore_IRQs(flags);
208 return retval;
209 }
210
211
212 sos_ret_t sos_kmutex_unlock(struct sos_kmutex *mutex)
213 {
214 sos_ui32_t flags;
215 sos_ret_t retval;
216
217 sos_disable_IRQs(flags);
218
219 if (sos_thread_get_current() != mutex->owner)
220 retval = -SOS_EPERM;
221
222 else if (sos_kwaitq_is_empty(& mutex->kwaitq))
223 {
224
225
226
227
228 mutex->owner = NULL;
229 retval = SOS_OK;
230 }
231 else
232 {
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247 #define MUTEX_STILL_LOCKED ((struct sos_thread*) 0x43)
248 mutex->owner = MUTEX_STILL_LOCKED;
249
250
251 retval = sos_kwaitq_wakeup(& mutex->kwaitq, 1, SOS_OK);
252 }
253
254 sos_restore_IRQs(flags);
255 return retval;
256 }