Diff markup
001 001
002 002
003 003
004 004
005 005
006 006
007 007
008 008
009 009
010 010
011 011
012 012
013 013
014 014
015 015
016 016
017 017
018 018
019 #include <sos/klibc.h> 019 #include <sos/klibc.h>
020 #include <sos/list.h> 020 #include <sos/list.h>
021 #include <sos/assert.h> 021 #include <sos/assert.h>
022 #include <hwcore/irq.h> 022 #include <hwcore/irq.h>
023 023
024 #include "kwaitq.h" 024 #include "kwaitq.h"
025 025
026 026
027 sos_ret_t sos_kwaitq_init(struct sos_kwaitq *k 027 sos_ret_t sos_kwaitq_init(struct sos_kwaitq *kwq,
028 const char *name, !! 028 const char *name)
029 sos_kwaitq_ordering_ <<
030 { 029 {
031 memset(kwq, 0x0, sizeof(struct sos_kwaitq)); 030 memset(kwq, 0x0, sizeof(struct sos_kwaitq));
032 031
033 #ifdef SOS_KWQ_DEBUG 032 #ifdef SOS_KWQ_DEBUG
034 if (! name) 033 if (! name)
035 name = "<unknown>"; 034 name = "<unknown>";
036 strzcpy(kwq->name, name, SOS_KWQ_DEBUG_MAX_N 035 strzcpy(kwq->name, name, SOS_KWQ_DEBUG_MAX_NAMELEN);
037 #endif 036 #endif
038 kwq->ordering = ordering; <<
039 list_init_named(kwq->waiting_list, 037 list_init_named(kwq->waiting_list,
040 prev_entry_in_kwaitq, next_e 038 prev_entry_in_kwaitq, next_entry_in_kwaitq);
041 039
042 return SOS_OK; 040 return SOS_OK;
043 } 041 }
044 042
045 043
046 sos_ret_t sos_kwaitq_dispose(struct sos_kwaitq 044 sos_ret_t sos_kwaitq_dispose(struct sos_kwaitq *kwq)
047 { 045 {
048 sos_ui32_t flags; 046 sos_ui32_t flags;
049 sos_ret_t retval; 047 sos_ret_t retval;
050 048
051 sos_disable_IRQs(flags); 049 sos_disable_IRQs(flags);
052 if (list_is_empty_named(kwq->waiting_list, 050 if (list_is_empty_named(kwq->waiting_list,
053 prev_entry_in_kwaitq 051 prev_entry_in_kwaitq, next_entry_in_kwaitq))
054 retval = SOS_OK; 052 retval = SOS_OK;
055 else 053 else
056 retval = -SOS_EBUSY; 054 retval = -SOS_EBUSY;
057 055
058 sos_restore_IRQs(flags); 056 sos_restore_IRQs(flags);
059 return retval; 057 return retval;
060 } 058 }
061 059
062 060
063 sos_bool_t sos_kwaitq_is_empty(const struct so 061 sos_bool_t sos_kwaitq_is_empty(const struct sos_kwaitq *kwq)
064 { 062 {
065 sos_ui32_t flags; 063 sos_ui32_t flags;
066 sos_ret_t retval; 064 sos_ret_t retval;
067 065
068 sos_disable_IRQs(flags); 066 sos_disable_IRQs(flags);
069 retval = list_is_empty_named(kwq->waiting_li 067 retval = list_is_empty_named(kwq->waiting_list,
070 prev_entry_in_k 068 prev_entry_in_kwaitq, next_entry_in_kwaitq);
071 069
072 sos_restore_IRQs(flags); 070 sos_restore_IRQs(flags);
073 return retval; 071 return retval;
074 } 072 }
075 073
076 074
077 sos_ret_t sos_kwaitq_init_entry(struct sos_kwa 075 sos_ret_t sos_kwaitq_init_entry(struct sos_kwaitq_entry *kwq_entry)
078 { 076 {
079 memset(kwq_entry, 0x0, sizeof(struct sos_kwa 077 memset(kwq_entry, 0x0, sizeof(struct sos_kwaitq_entry));
080 kwq_entry->thread = sos_thread_get_current() 078 kwq_entry->thread = sos_thread_get_current();
081 return SOS_OK; 079 return SOS_OK;
082 } 080 }
083 081
084 082
085 083
086 !! 084
087 inline static sos_ret_t !! 085
088 _kwaitq_add_entry(struct sos_kwaitq *kwq, !! 086 inline static sos_ret_t _kwaitq_add_entry(struct sos_kwaitq *kwq,
089 struct sos_kwaitq_entry *kwq !! 087 struct sos_kwaitq_entry *kwq_entry)
090 sos_sched_priority_t prio) <<
091 { 088 {
092 struct sos_kwaitq_entry *next_entry = NULL, <<
093 int nb_entries; <<
094 <<
095 089
096 SOS_ASSERT_FATAL(NULL == kwq_entry->kwaitq); 090 SOS_ASSERT_FATAL(NULL == kwq_entry->kwaitq);
097 091
098 092
099 SOS_ASSERT_FATAL(NULL != kwq_entry->thread); 093 SOS_ASSERT_FATAL(NULL != kwq_entry->thread);
100 094
101 095
102 kwq_entry->wakeup_triggered = FALSE; 096 kwq_entry->wakeup_triggered = FALSE;
103 kwq_entry->wakeup_status = SOS_OK; 097 kwq_entry->wakeup_status = SOS_OK;
104 098
105 !! 099
106 switch (kwq->ordering) !! 100 list_add_tail_named(kwq->waiting_list, kwq_entry,
107 { !! 101 prev_entry_in_kwaitq, next_entry_in_kwaitq);
108 case SOS_KWQ_ORDER_FIFO: <<
109 <<
110 { <<
111 <<
112 list_add_tail_named(kwq->waiting_list, <<
113 prev_entry_in_kwai <<
114 } <<
115 break; <<
116 <<
117 case SOS_KWQ_ORDER_PRIO: <<
118 <<
119 { <<
120 <<
121 <<
122 list_foreach_forward_named(kwq->waitin <<
123 prev_entry_ <<
124 { <<
125 <<
126 <<
127 if (SOS_SCHED_PRIO_CMP(prio, <<
128 sos_thread_ <<
129 > 0) <<
130 { <<
131 <<
132 next_entry = entry; <<
133 break; <<
134 } <<
135 } <<
136 <<
137 <<
138 if (next_entry != NULL) <<
139 { <<
140 list_insert_before_named(kwq->wait <<
141 prev_entr <<
142 next_entr <<
143 } <<
144 else <<
145 { <<
146 <<
147 <<
148 list_add_tail_named(kwq->waiting_l <<
149 prev_entry_in_ <<
150 } <<
151 } <<
152 break; <<
153 <<
154 default: <<
155 SOS_FATAL_ERROR("Invalid kwq ordering %d <<
156 break; <<
157 } <<
158 102
159 103
160 list_add_tail_named(kwq_entry->thread->kwait 104 list_add_tail_named(kwq_entry->thread->kwaitq_list, kwq_entry,
161 prev_entry_for_thread, n 105 prev_entry_for_thread, next_entry_for_thread);
162 106
163 kwq_entry->kwaitq = kwq; 107 kwq_entry->kwaitq = kwq;
164 !! 108
165 return SOS_OK; 109 return SOS_OK;
166 } 110 }
167 111
168 112
169 sos_ret_t sos_kwaitq_add_entry(struct sos_kwai 113 sos_ret_t sos_kwaitq_add_entry(struct sos_kwaitq *kwq,
170 struct sos_kwai 114 struct sos_kwaitq_entry *kwq_entry)
171 { 115 {
172 sos_ui32_t flags; 116 sos_ui32_t flags;
173 sos_ret_t retval; 117 sos_ret_t retval;
174 118
175 sos_disable_IRQs(flags); 119 sos_disable_IRQs(flags);
176 retval = _kwaitq_add_entry(kwq, kwq_entry, !! 120 retval = _kwaitq_add_entry(kwq, kwq_entry);
177 sos_thread_get_pr <<
178 sos_restore_IRQs(flags); 121 sos_restore_IRQs(flags);
179 122
180 return retval; 123 return retval;
181 } 124 }
182 125
183 126
184 127
185 128
186 inline static sos_ret_t 129 inline static sos_ret_t
187 _kwaitq_remove_entry(struct sos_kwaitq *kwq, 130 _kwaitq_remove_entry(struct sos_kwaitq *kwq,
188 struct sos_kwaitq_entry * 131 struct sos_kwaitq_entry *kwq_entry)
189 { 132 {
190 SOS_ASSERT_FATAL(kwq_entry->kwaitq == kwq); 133 SOS_ASSERT_FATAL(kwq_entry->kwaitq == kwq);
191 134
192 list_delete_named(kwq->waiting_list, kwq_ent 135 list_delete_named(kwq->waiting_list, kwq_entry,
193 prev_entry_in_kwaitq, next 136 prev_entry_in_kwaitq, next_entry_in_kwaitq);
194 137
195 list_delete_named(kwq_entry->thread->kwaitq_ 138 list_delete_named(kwq_entry->thread->kwaitq_list, kwq_entry,
196 prev_entry_for_thread, nex 139 prev_entry_for_thread, next_entry_for_thread);
197 140
198 kwq_entry->kwaitq = NULL; 141 kwq_entry->kwaitq = NULL;
199 return SOS_OK; 142 return SOS_OK;
200 } 143 }
201 144
202 145
203 sos_ret_t sos_kwaitq_remove_entry(struct sos_k 146 sos_ret_t sos_kwaitq_remove_entry(struct sos_kwaitq *kwq,
204 struct sos_k 147 struct sos_kwaitq_entry *kwq_entry)
205 { 148 {
206 sos_ui32_t flags; 149 sos_ui32_t flags;
207 sos_ret_t retval; 150 sos_ret_t retval;
208 151
209 sos_disable_IRQs(flags); 152 sos_disable_IRQs(flags);
210 retval = _kwaitq_remove_entry(kwq, kwq_entry 153 retval = _kwaitq_remove_entry(kwq, kwq_entry);
211 sos_restore_IRQs(flags); 154 sos_restore_IRQs(flags);
212 155
213 return retval; 156 return retval;
214 } 157 }
215 158
216 159
217 sos_ret_t sos_kwaitq_wait(struct sos_kwaitq *k 160 sos_ret_t sos_kwaitq_wait(struct sos_kwaitq *kwq,
218 struct sos_time *tim 161 struct sos_time *timeout)
219 { 162 {
220 sos_ui32_t flags; 163 sos_ui32_t flags;
221 sos_ret_t retval; 164 sos_ret_t retval;
222 struct sos_kwaitq_entry kwq_entry; 165 struct sos_kwaitq_entry kwq_entry;
223 166
224 sos_kwaitq_init_entry(& kwq_entry); 167 sos_kwaitq_init_entry(& kwq_entry);
225 168
226 sos_disable_IRQs(flags); 169 sos_disable_IRQs(flags);
227 170
228 retval = _kwaitq_add_entry(kwq, & kwq_entry, !! 171 retval = _kwaitq_add_entry(kwq, & kwq_entry);
229 sos_thread_get_pr <<
230 172
231 173
232 sos_thread_sleep(timeout); 174 sos_thread_sleep(timeout);
233 175
234 176
235 177
236 if (! kwq_entry.wakeup_triggered) 178 if (! kwq_entry.wakeup_triggered)
237 { 179 {
238 180
239 181
240 _kwaitq_remove_entry(kwq, & kwq_entry); 182 _kwaitq_remove_entry(kwq, & kwq_entry);
241 retval = -SOS_EINTR; 183 retval = -SOS_EINTR;
242 } 184 }
243 else 185 else
244 { 186 {
245 retval = kwq_entry.wakeup_status; 187 retval = kwq_entry.wakeup_status;
246 } 188 }
247 189
248 sos_restore_IRQs(flags); 190 sos_restore_IRQs(flags);
249 191
250 192
251 return retval; 193 return retval;
252 } 194 }
253 195
254 196
255 sos_ret_t sos_kwaitq_wakeup(struct sos_kwaitq 197 sos_ret_t sos_kwaitq_wakeup(struct sos_kwaitq *kwq,
256 unsigned int nb_th 198 unsigned int nb_threads,
257 sos_ret_t wakeup_s 199 sos_ret_t wakeup_status)
258 { 200 {
259 sos_ui32_t flags; 201 sos_ui32_t flags;
260 202
261 sos_disable_IRQs(flags); 203 sos_disable_IRQs(flags);
262 204
263 205
264 !! 206
265 <<
266 while (! list_is_empty_named(kwq->waiting_li 207 while (! list_is_empty_named(kwq->waiting_list,
267 prev_entry_in_k 208 prev_entry_in_kwaitq, next_entry_in_kwaitq))
268 { 209 {
269 struct sos_kwaitq_entry *kwq_entry 210 struct sos_kwaitq_entry *kwq_entry
270 = list_get_head_named(kwq->waiting_lis 211 = list_get_head_named(kwq->waiting_list,
271 prev_entry_in_kw 212 prev_entry_in_kwaitq, next_entry_in_kwaitq);
272 213
273 214
274 if (nb_threads <= 0) 215 if (nb_threads <= 0)
275 break; 216 break;
276 217
277 218
278 219
279 220
280 221
281 222
282 if (SOS_THR_RUNNING == sos_thread_get_st 223 if (SOS_THR_RUNNING == sos_thread_get_state(kwq_entry->thread))
283 { 224 {
284 225
285 226
286 227
287 228
288 continue; 229 continue;
289 } 230 }
290 else 231 else
291 { 232 {
292 233
293 sos_sched_set_ready(kwq_entry->threa 234 sos_sched_set_ready(kwq_entry->thread);
294 } 235 }
295 236
296 237
297 _kwaitq_remove_entry(kwq, kwq_entry); 238 _kwaitq_remove_entry(kwq, kwq_entry);
298 kwq_entry->wakeup_triggered = TRUE; 239 kwq_entry->wakeup_triggered = TRUE;
299 kwq_entry->wakeup_status = wakeup_sta 240 kwq_entry->wakeup_status = wakeup_status;
300 241
301 242
302 nb_threads --; 243 nb_threads --;
303 } 244 }
304 245
305 sos_restore_IRQs(flags); 246 sos_restore_IRQs(flags);
306 <<
307 return SOS_OK; <<
308 } <<
309 <<
310 <<
311 <<
312 sos_ret_t sos_kwaitq_change_priority(struct so <<
313 struct so <<
314 sos_sched <<
315 { <<
316 <<
317 _kwaitq_remove_entry(kwq, kwq_entry); <<
318 _kwaitq_add_entry(kwq, kwq_entry, priority); <<
319 247
320 return SOS_OK; 248 return SOS_OK;
321 } 249 }