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