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