source: asp_ewarm/asp-1.7.0/extension/mutex/test/bit_kernel.c@ 61

Last change on this file since 61 was 61, checked in by ertl-honda, 11 years ago

ASP for EWARM のコミット.

File size: 11.8 KB
Line 
1/*
2 * TOPPERS/ASP Kernel
3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Advanced Standard Profile Kernel
5 *
6 * Copyright (C) 2005-2008 by Embedded and Real-Time Systems Laboratory
7 * Graduate School of Information Science, Nagoya Univ., JAPAN
8 *
9 * ã‹L’˜ìŒ ŽÒ‚́CˆÈ‰º‚Ì(1)`(4)‚ÌðŒ‚ð–ž‚½‚·ê‡‚ÉŒÀ‚èC–{ƒ\ƒtƒgƒEƒF
10 * ƒAi–{ƒ\ƒtƒgƒEƒFƒA‚ð‰ü•Ï‚µ‚½‚à‚Ì‚ðŠÜ‚ށDˆÈ‰º“¯‚¶j‚ðŽg—pE•¡»E‰ü
11 * •ÏEÄ”z•ziˆÈ‰ºC—˜—p‚ƌĂԁj‚·‚邱‚Ƃ𖳏ž‚Å‹–‘ø‚·‚éD
12 * (1) –{ƒ\ƒtƒgƒEƒFƒA‚ðƒ\[ƒXƒR[ƒh‚ÌŒ`‚Å—˜—p‚·‚éê‡‚ɂ́Cã‹L‚Ì’˜ì
13 * Œ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L‚Ì–³•ÛØ‹K’肪C‚»‚Ì‚Ü‚Ü‚ÌŒ`‚Ń\[
14 * ƒXƒR[ƒh’†‚ÉŠÜ‚Ü‚ê‚Ä‚¢‚邱‚ƁD
15 * (2) –{ƒ\ƒtƒgƒEƒFƒA‚ðCƒ‰ƒCƒuƒ‰ƒŠŒ`Ž®‚ȂǁC‘¼‚̃\ƒtƒgƒEƒFƒAŠJ”­‚ÉŽg
16 * —p‚Å‚«‚éŒ`‚ōĔz•z‚·‚éê‡‚ɂ́CÄ”z•z‚É”º‚¤ƒhƒLƒ…
17ƒƒ“ƒgi—˜—p
18 * ŽÒƒ}ƒjƒ…
19ƒAƒ‹‚Ȃǁj‚ɁCã‹L‚Ì’˜ìŒ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L
20 * ‚Ì–³•ÛØ‹K’è‚ðŒfÚ‚·‚邱‚ƁD
21 * (3) –{ƒ\ƒtƒgƒEƒFƒA‚ðC‹@Ší‚É‘g‚ݍž‚ނȂǁC‘¼‚̃\ƒtƒgƒEƒFƒAŠJ”­‚ÉŽg
22 * —p‚Å‚«‚È‚¢Œ`‚ōĔz•z‚·‚éê‡‚ɂ́CŽŸ‚Ì‚¢‚¸‚ê‚©‚ÌðŒ‚ð–ž‚½‚·‚±
23 * ‚ƁD
24 * (a) Ä”z•z‚É”º‚¤ƒhƒLƒ…
25ƒƒ“ƒgi—˜—pŽÒƒ}ƒjƒ…
26ƒAƒ‹‚Ȃǁj‚ɁCã‹L‚Ì’˜
27 * ìŒ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L‚Ì–³•ÛØ‹K’è‚ðŒfÚ‚·‚邱‚ƁD
28 * (b) Ä”z•z‚ÌŒ`‘Ô‚ðC•Ê‚É’è‚ß‚é•û–@‚É‚æ‚Á‚āCTOPPERSƒvƒƒWƒFƒNƒg‚É
29 * •ñ‚·‚邱‚ƁD
30 * (4) –{ƒ\ƒtƒgƒEƒFƒA‚Ì—˜—p‚É‚æ‚è’¼Ú“I‚Ü‚½‚͊ԐړI‚ɐ¶‚¶‚é‚¢‚©‚Ȃ鑹
31 * ŠQ‚©‚ç‚àCã‹L’˜ìŒ ŽÒ‚¨‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚ð–Ɛӂ·‚邱‚ƁD
32 * ‚Ü‚½C–{ƒ\ƒtƒgƒEƒFƒA‚̃†[ƒU‚Ü‚½‚̓Gƒ“ƒhƒ†[ƒU‚©‚ç‚Ì‚¢‚©‚Ȃ闝
33 * —R‚ÉŠî‚­¿‹‚©‚ç‚àCã‹L’˜ìŒ ŽÒ‚¨‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚ð
34 * –Ɛӂ·‚邱‚ƁD
35 *
36 * –{ƒ\ƒtƒgƒEƒFƒA‚́C–³•ÛØ‚Å’ñ‹Ÿ‚³‚ê‚Ä‚¢‚é‚à‚Ì‚Å‚ ‚éDã‹L’˜ìŒ ŽÒ‚¨
37 * ‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚́C–{ƒ\ƒtƒgƒEƒFƒA‚ÉŠÖ‚µ‚āC“Á’è‚ÌŽg—p–Ú“I
38 * ‚ɑ΂·‚é“K‡«‚àŠÜ‚߂āC‚¢‚©‚È‚é•ÛØ‚às‚í‚È‚¢D‚Ü‚½C–{ƒ\ƒtƒgƒEƒF
39 * ƒA‚Ì—˜—p‚É‚æ‚è’¼Ú“I‚Ü‚½‚͊ԐړI‚ɐ¶‚¶‚½‚¢‚©‚Ȃ鑹ŠQ‚ÉŠÖ‚µ‚Ä‚àC‚»
40 * ‚̐ӔC‚𕉂í‚È‚¢D
41 *
42 * @(#) $Id: bit_kernel.c 1544 2009-05-08 07:53:48Z ertl-hiro $
43 */
44
45/*
46 * ƒJ[ƒlƒ‹‚̐®‡«ŒŸ¸
47 */
48
49#include "kernel/kernel_impl.h"
50#include "kernel/task.h"
51#include "kernel/wait.h"
52#include "kernel/semaphore.h"
53#include "kernel/eventflag.h"
54#include "kernel/dataqueue.h"
55#include "kernel/pridataq.h"
56#include "kernel/mailbox.h"
57#include "kernel/mutex.h"
58#include "kernel/mempfix.h"
59#include "kernel/time_event.h"
60
61/*
62 * ƒGƒ‰[ƒR[ƒh‚Ì’è‹`
63 */
64#define E_SYS_LINENO ERCD(E_SYS, -(__LINE__))
65
66/*
67 * ŠÇ—ƒuƒƒbƒN‚̃AƒhƒŒƒX‚̐³“–«‚̃`ƒFƒbƒN
68 */
69#define VALID_TCB(p_tcb) \
70 ((((char *) p_tcb) - ((char *) tcb_table)) % sizeof(TCB) == 0 \
71 && TMIN_TSKID <= TSKID(p_tcb) && TSKID(p_tcb) <= tmax_tskid)
72
73#define VALID_SEMCB(p_semcb) \
74 ((((char *) p_semcb) - ((char *) semcb_table)) % sizeof(SEMCB) == 0 \
75 && TMIN_SEMID <= SEMID(p_semcb) && SEMID(p_semcb) <= tmax_semid)
76
77#define VALID_FLGCB(p_flgcb) \
78 ((((char *) p_flgcb) - ((char *) flgcb_table)) % sizeof(FLGCB) == 0 \
79 && TMIN_FLGID <= FLGID(p_flgcb) && FLGID(p_flgcb) <= tmax_flgid)
80
81#define VALID_DTQCB(p_dtqcb) \
82 ((((char *) p_dtqcb) - ((char *) dtqcb_table)) % sizeof(DTQCB) == 0 \
83 && TMIN_DTQID <= DTQID(p_dtqcb) && DTQID(p_dtqcb) <= tmax_dtqid)
84
85#define VALID_PDQCB(p_pdqcb) \
86 ((((char *) p_pdqcb) - ((char *) pdqcb_table)) % sizeof(PDQCB) == 0 \
87 && TMIN_PDQID <= PDQID(p_pdqcb) && PDQID(p_pdqcb) <= tmax_pdqid)
88
89#define VALID_MBXCB(p_mbxcb) \
90 ((((char *) p_mbxcb) - ((char *) mbxcb_table)) % sizeof(MBXCB) == 0 \
91 && TMIN_MBXID <= MBXID(p_mbxcb) && MBXID(p_mbxcb) <= tmax_mbxid)
92
93#define VALID_MTXCB(p_mtxcb) \
94 ((((char *) p_mtxcb) - ((char *) mtxcb_table)) % sizeof(MTXCB) == 0 \
95 && TMIN_MTXID <= MTXID(p_mtxcb) && MTXID(p_mtxcb) <= tmax_mtxid)
96
97#define VALID_MPFCB(p_mpfcb) \
98 ((((char *) p_mpfcb) - ((char *) mpfcb_table)) % sizeof(MPFCB) == 0 \
99 && TMIN_MPFID <= MPFID(p_mpfcb) && MPFID(p_mpfcb) <= tmax_mpfid)
100
101/*
102 * ƒLƒ…
103[‚̃`ƒFƒbƒN‚Ì‚½‚߂̊֐”
104 *
105 * p_queue‚Ép_entry‚ªŠÜ‚Ü‚ê‚Ä‚¢‚é‚©‚𒲂ׂéDŠÜ‚Ü‚ê‚Ä‚¢‚ê‚ÎtrueCŠÜ‚Ü
106 * ‚ê‚Ä‚¢‚È‚¢ê‡‚É‚Ífalse‚ð•Ô‚·Dƒ_ƒuƒ‹ƒŠƒ“ƒN‚Ì•s®‡‚̏ꍇ‚É‚àC
107 * false‚ð•Ô‚·D
108 */
109static bool_t
110in_queue(QUEUE *p_queue, QUEUE *p_entry)
111{
112 QUEUE *p_current, *p_next;
113
114 p_current = p_queue->p_next;
115 if (p_current->p_prev != p_queue) {
116 return(false); /* ƒ_ƒuƒ‹ƒŠƒ“ƒN‚Ì•s®‡ */
117 }
118 while (p_current != p_queue) {
119 if (p_current == p_entry) {
120 return(true); /* p_entry‚ªŠÜ‚Ü‚ê‚Ä‚¢‚½ */
121 }
122
123 /*
124 * ƒLƒ…
125[‚ÌŽŸ‚Ì—v‘f‚ɐi‚Þ
126 */
127 p_next = p_current->p_next;
128 if (p_next->p_prev != p_current) {
129 return(false); /* ƒ_ƒuƒ‹ƒŠƒ“ƒN‚Ì•s®‡ */
130 }
131 p_current = p_next;
132 }
133 return(false);
134}
135
136/*
137 * ƒXƒ^ƒbƒNã‚ðŽw‚µ‚Ä‚¢‚é‚©‚ÌŒŸ¸
138 */
139static bool_t
140on_stack(void *addr, const TINIB *p_tinib)
141{
142 if (p_tinib->stk <= addr
143 && addr < (void *)((char *)(p_tinib->stk) + p_tinib->stksz)) {
144 return(true);
145 }
146 return(false);
147}
148
149/*
150 * ƒ^ƒXƒN–ˆ‚̐®‡«ŒŸ¸
151 */
152static ER
153bit_task(ID tskid)
154{
155 TCB *p_tcb;
156 const TINIB *p_tinib;
157 uint_t tstat, tstat_wait, priority;
158 TMEVTB *p_tmevtb;
159 SEMCB *p_semcb;
160 FLGCB *p_flgcb;
161 DTQCB *p_dtqcb;
162 PDQCB *p_pdqcb;
163 MBXCB *p_mbxcb;
164 MTXCB *p_mtxcb;
165 MPFCB *p_mpfcb;
166
167 if (!(TMIN_TSKID <= (tskid) && (tskid) <= tmax_tskid)) {
168 return(E_ID);
169 }
170 p_tcb = get_tcb(tskid);
171 p_tinib = p_tcb->p_tinib;
172 tstat = p_tcb->tstat;
173 tstat_wait = (tstat & TS_WAIT_MASK);
174 priority = p_tcb->priority;
175
176 /*
177 * ‰Šú‰»ƒuƒƒbƒN‚ւ̃|ƒCƒ“ƒ^‚ÌŒŸ¸
178 */
179 if (p_tinib != &(tinib_table[INDEX_TSK(tskid)])) {
180 return(E_SYS_LINENO);
181 }
182
183 /*
184 * tstat‚ÌŒŸ¸
185 */
186 switch (tstat & (TS_RUNNABLE | TS_WAITING | TS_SUSPENDED)) {
187 case TS_DORMANT:
188 if (tstat != TS_DORMANT) {
189 return(E_SYS_LINENO);
190 }
191 break;
192 case TS_RUNNABLE:
193 if (tstat != TS_RUNNABLE) {
194 return(E_SYS_LINENO);
195 }
196 break;
197 case TS_WAITING:
198 case (TS_WAITING | TS_SUSPENDED):
199 if (!(TS_WAIT_DLY <= tstat_wait && tstat_wait <= TS_WAIT_MTX)) {
200 return(E_SYS_LINENO);
201 }
202 if ((tstat & ~(TS_WAIT_MASK | TS_RUNNABLE | TS_WAITING | TS_SUSPENDED))
203 != 0U) {
204 return(E_SYS_LINENO);
205 }
206 break;
207 case TS_SUSPENDED:
208 if (tstat != TS_SUSPENDED) {
209 return(E_SYS_LINENO);
210 }
211 break;
212 default:
213 return(E_SYS_LINENO);
214 }
215
216 /*
217 * actque‚ÌŒŸ¸
218 */
219 if (TSTAT_DORMANT(tstat) && p_tcb->actque) {
220 return(E_SYS_LINENO);
221 }
222
223 /*
224 * ƒ^ƒXƒN—Dæ“x‚ÌŒŸ¸
225 */
226 if (priority >= TNUM_TPRI) {
227 return(E_SYS_LINENO);
228 }
229
230 /*
231 * texptn‚ÌŒŸ¸
232 */
233 if (p_tcb->p_tinib->texrtn == NULL && p_tcb->texptn != 0U) {
234 return(E_SYS_LINENO);
235 }
236
237 /*
238 * ‹xŽ~ó‘Ô‚É‚¨‚¯‚éƒ`ƒFƒbƒN
239 */
240 if (TSTAT_DORMANT(tstat)) {
241 if (!(priority == p_tinib->ipriority)
242 && (p_tcb->wupque == false)
243 && (p_tcb->enatex == false)
244 && (p_tcb->texptn == 0U)) {
245 return(E_SYS_LINENO);
246 }
247 }
248
249 /*
250 * ŽÀs‚Å‚«‚éó‘Ô‚É‚¨‚¯‚éƒ`ƒFƒbƒN
251 */
252 if (TSTAT_RUNNABLE(tstat)) {
253 if (!in_queue(&ready_queue[priority], &(p_tcb->task_queue))) {
254 return(E_SYS_LINENO);
255 }
256 }
257
258 /*
259 * ‘Ò‚¿ó‘Ô‚É‚¨‚¯‚éƒ`ƒFƒbƒN
260 */
261 if (TSTAT_WAITING(tstat)) {
262 if (!on_stack(p_tcb->p_winfo, p_tinib)) {
263 return(E_SYS_LINENO);
264 }
265 p_tmevtb = p_tcb->p_winfo->p_tmevtb;
266 if (p_tmevtb != NULL) {
267 if (!on_stack(p_tmevtb, p_tinib)) {
268 return(E_SYS_LINENO);
269 }
270 /*
271 * (*p_tmevtb)‚ÌŒŸ¸i–¢Š®¬j
272 */
273 }
274
275 switch (tstat & TS_WAIT_MASK) {
276 case TS_WAIT_SLP:
277 if (p_tcb->wupque == true) {
278 return(E_SYS_LINENO);
279 }
280 break;
281
282 case TS_WAIT_DLY:
283 if (p_tmevtb == NULL) {
284 return(E_SYS_LINENO);
285 }
286 break;
287
288 case TS_WAIT_SEM:
289 p_semcb = ((WINFO_SEM *)(p_tcb->p_winfo))->p_semcb;
290 if (!VALID_SEMCB(p_semcb)) {
291 return(E_SYS_LINENO);
292 }
293 if (!in_queue(&(p_semcb->wait_queue), &(p_tcb->task_queue))) {
294 return(E_SYS_LINENO);
295 }
296 break;
297
298 case TS_WAIT_FLG:
299 p_flgcb = ((WINFO_FLG *)(p_tcb->p_winfo))->p_flgcb;
300 if (!VALID_FLGCB(p_flgcb)) {
301 return(E_SYS_LINENO);
302 }
303 if (!in_queue(&(p_flgcb->wait_queue), &(p_tcb->task_queue))) {
304 return(E_SYS_LINENO);
305 }
306 break;
307
308 case TS_WAIT_SDTQ:
309 p_dtqcb = ((WINFO_DTQ *)(p_tcb->p_winfo))->p_dtqcb;
310 if (!VALID_DTQCB(p_dtqcb)) {
311 return(E_SYS_LINENO);
312 }
313 if (!in_queue(&(p_dtqcb->swait_queue), &(p_tcb->task_queue))) {
314 return(E_SYS_LINENO);
315 }
316 break;
317
318 case TS_WAIT_RDTQ:
319 p_dtqcb = ((WINFO_DTQ *)(p_tcb->p_winfo))->p_dtqcb;
320 if (!VALID_DTQCB(p_dtqcb)) {
321 return(E_SYS_LINENO);
322 }
323 if (!in_queue(&(p_dtqcb->rwait_queue), &(p_tcb->task_queue))) {
324 return(E_SYS_LINENO);
325 }
326 break;
327
328 case TS_WAIT_SPDQ:
329 p_pdqcb = ((WINFO_PDQ *)(p_tcb->p_winfo))->p_pdqcb;
330 if (!VALID_PDQCB(p_pdqcb)) {
331 return(E_SYS_LINENO);
332 }
333 if (!in_queue(&(p_pdqcb->swait_queue), &(p_tcb->task_queue))) {
334 return(E_SYS_LINENO);
335 }
336 break;
337
338 case TS_WAIT_RPDQ:
339 p_pdqcb = ((WINFO_PDQ *)(p_tcb->p_winfo))->p_pdqcb;
340 if (!VALID_PDQCB(p_pdqcb)) {
341 return(E_SYS_LINENO);
342 }
343 if (!in_queue(&(p_pdqcb->rwait_queue), &(p_tcb->task_queue))) {
344 return(E_SYS_LINENO);
345 }
346 break;
347
348 case TS_WAIT_MBX:
349 p_mbxcb = ((WINFO_MBX *)(p_tcb->p_winfo))->p_mbxcb;
350 if (!VALID_MBXCB(p_mbxcb)) {
351 return(E_SYS_LINENO);
352 }
353 if (!in_queue(&(p_mbxcb->wait_queue), &(p_tcb->task_queue))) {
354 return(E_SYS_LINENO);
355 }
356 break;
357
358 case TS_WAIT_MTX:
359 p_mtxcb = ((WINFO_MTX *)(p_tcb->p_winfo))->p_mtxcb;
360 if (!VALID_MTXCB(p_mtxcb)) {
361 return(E_SYS_LINENO);
362 }
363 if (!in_queue(&(p_mtxcb->wait_queue), &(p_tcb->task_queue))) {
364 return(E_SYS_LINENO);
365 }
366 break;
367
368 case TS_WAIT_MPF:
369 p_mpfcb = ((WINFO_MPF *)(p_tcb->p_winfo))->p_mpfcb;
370 if (!VALID_MPFCB(p_mpfcb)) {
371 return(E_SYS_LINENO);
372 }
373 if (!in_queue(&(p_mpfcb->wait_queue), &(p_tcb->task_queue))) {
374 return(E_SYS_LINENO);
375 }
376 break;
377 }
378 }
379
380 /*
381 * tskctxb‚ÌŒŸ¸
382 */
383 if (!TSTAT_DORMANT(tstat) && p_tcb != p_runtsk) {
384 /*
385 * ƒ^[ƒQƒbƒgˆË‘¶‚ÌŒŸ¸
386 */
387#if 0
388 if (bit_tskctxb(&(p_tcb->tskctxb))) {
389 return(E_SYS_LINENO);
390 }
391#endif
392 }
393 return(E_OK);
394}
395
396/*
397 * ƒZƒ}ƒtƒH–ˆ‚̐®‡«ŒŸ¸
398 */
399#define INDEX_SEM(semid) ((uint_t)((semid) - TMIN_SEMID))
400#define get_semcb(semid) (&(semcb_table[INDEX_SEM(semid)]))
401
402static ER
403bit_semaphore(ID semid)
404{
405 SEMCB *p_semcb;
406 const SEMINIB *p_seminib;
407 uint_t semcnt;
408 QUEUE *p_queue;
409 TCB *p_tcb;
410
411 if (!(TMIN_SEMID <= (semid) && (semid) <= tmax_semid)) {
412 return(E_ID);
413 }
414 p_semcb = get_semcb(semid);
415 p_seminib = p_semcb->p_seminib;
416 semcnt = p_semcb->semcnt;
417
418 /*
419 * ‰Šú‰»ƒuƒƒbƒN‚ւ̃|ƒCƒ“ƒ^‚ÌŒŸ¸
420 */
421 if (p_seminib != &(seminib_table[INDEX_SEM(semid)])) {
422 return(E_SYS_LINENO);
423 }
424
425 /*
426 * semcnt‚ÌŒŸ¸
427 */
428 if (semcnt > p_seminib->maxsem) {
429 return(E_SYS_LINENO);
430 }
431
432 /*
433 * wait_queue‚ÌŒŸ¸
434 */
435 if (semcnt == 0) {
436 p_queue = p_semcb->wait_queue.p_next;
437 while (p_queue != &(p_semcb->wait_queue)) {
438 p_tcb = (TCB *) p_queue;
439 p_queue = p_queue->p_next;
440 if (!VALID_TCB(p_tcb)) {
441 return(E_SYS_LINENO);
442 }
443 if (p_tcb->tstat != (TS_WAITING | TS_WAIT_SEM)) {
444 return(E_SYS_LINENO);
445 }
446 if (p_semcb != ((WINFO_SEM *)(p_tcb->p_winfo))->p_semcb) {
447 return(E_SYS_LINENO);
448 }
449 }
450 }
451 else {
452 if (!queue_empty(&(p_semcb->wait_queue))) {
453 return(E_SYS_LINENO);
454 }
455 }
456 return(E_OK);
457}
458
459/*
460 * ®‡«ŒŸ¸ƒ‹[ƒ`ƒ“–{‘Ì
461 */
462ER
463bit_kernel(void)
464{
465 ID tskid;
466 ID semid;
467 ER ercd;
468
469 /*
470 * ƒ^ƒXƒN–ˆ‚ÌŒŸ¸
471 */
472 for (tskid = TMIN_TSKID; tskid <= tmax_tskid; tskid++) {
473 ercd = bit_task(tskid);
474 if (ercd != E_OK) {
475 return(ercd);
476 }
477 }
478
479 /*
480 * ƒZƒ}ƒtƒH–ˆ‚ÌŒŸ¸
481 */
482 for (semid = TMIN_SEMID; semid <= tmax_semid; semid++) {
483 ercd = bit_semaphore(semid);
484 if (ercd != E_OK) {
485 return(ercd);
486 }
487 }
488
489 return(E_OK);
490}
Note: See TracBrowser for help on using the repository browser.