source: asp_ewarm/asp-1.7.0/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.3 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 1234 2008-08-09 14:24:38Z 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/mempfix.h"
58#include "kernel/time_event.h"
59
60/*
61 * ƒGƒ‰[ƒR[ƒh‚Ì’è‹`
62 */
63#define E_SYS_LINENO ERCD(E_SYS, -(__LINE__))
64
65/*
66 * ŠÇ—ƒuƒƒbƒN‚̃AƒhƒŒƒX‚̐³“–«‚̃`ƒFƒbƒN
67 */
68#define VALID_TCB(p_tcb) \
69 ((((char *) p_tcb) - ((char *) tcb_table)) % sizeof(TCB) == 0 \
70 && TMIN_TSKID <= TSKID(p_tcb) && TSKID(p_tcb) <= tmax_tskid)
71
72#define VALID_SEMCB(p_semcb) \
73 ((((char *) p_semcb) - ((char *) semcb_table)) % sizeof(SEMCB) == 0 \
74 && TMIN_SEMID <= SEMID(p_semcb) && SEMID(p_semcb) <= tmax_semid)
75
76#define VALID_FLGCB(p_flgcb) \
77 ((((char *) p_flgcb) - ((char *) flgcb_table)) % sizeof(FLGCB) == 0 \
78 && TMIN_FLGID <= FLGID(p_flgcb) && FLGID(p_flgcb) <= tmax_flgid)
79
80#define VALID_DTQCB(p_dtqcb) \
81 ((((char *) p_dtqcb) - ((char *) dtqcb_table)) % sizeof(DTQCB) == 0 \
82 && TMIN_DTQID <= DTQID(p_dtqcb) && DTQID(p_dtqcb) <= tmax_dtqid)
83
84#define VALID_PDQCB(p_pdqcb) \
85 ((((char *) p_pdqcb) - ((char *) pdqcb_table)) % sizeof(PDQCB) == 0 \
86 && TMIN_PDQID <= PDQID(p_pdqcb) && PDQID(p_pdqcb) <= tmax_pdqid)
87
88#define VALID_MBXCB(p_mbxcb) \
89 ((((char *) p_mbxcb) - ((char *) mbxcb_table)) % sizeof(MBXCB) == 0 \
90 && TMIN_MBXID <= MBXID(p_mbxcb) && MBXID(p_mbxcb) <= tmax_mbxid)
91
92#define VALID_MPFCB(p_mpfcb) \
93 ((((char *) p_mpfcb) - ((char *) mpfcb_table)) % sizeof(MPFCB) == 0 \
94 && TMIN_MPFID <= MPFID(p_mpfcb) && MPFID(p_mpfcb) <= tmax_mpfid)
95
96/*
97 * ƒLƒ…
98[‚̃`ƒFƒbƒN‚Ì‚½‚߂̊֐”
99 *
100 * p_queue‚Ép_entry‚ªŠÜ‚Ü‚ê‚Ä‚¢‚é‚©‚𒲂ׂéDŠÜ‚Ü‚ê‚Ä‚¢‚ê‚ÎtrueCŠÜ‚Ü
101 * ‚ê‚Ä‚¢‚È‚¢ê‡‚É‚Ífalse‚ð•Ô‚·Dƒ_ƒuƒ‹ƒŠƒ“ƒN‚Ì•s®‡‚̏ꍇ‚É‚àC
102 * false‚ð•Ô‚·D
103 */
104static bool_t
105in_queue(QUEUE *p_queue, QUEUE *p_entry)
106{
107 QUEUE *p_current, *p_next;
108
109 p_current = p_queue->p_next;
110 if (p_current->p_prev != p_queue) {
111 return(false); /* ƒ_ƒuƒ‹ƒŠƒ“ƒN‚Ì•s®‡ */
112 }
113 while (p_current != p_queue) {
114 if (p_current == p_entry) {
115 return(true); /* p_entry‚ªŠÜ‚Ü‚ê‚Ä‚¢‚½ */
116 }
117
118 /*
119 * ƒLƒ…
120[‚ÌŽŸ‚Ì—v‘f‚ɐi‚Þ
121 */
122 p_next = p_current->p_next;
123 if (p_next->p_prev != p_current) {
124 return(false); /* ƒ_ƒuƒ‹ƒŠƒ“ƒN‚Ì•s®‡ */
125 }
126 p_current = p_next;
127 }
128 return(false);
129}
130
131/*
132 * ƒXƒ^ƒbƒNã‚ðŽw‚µ‚Ä‚¢‚é‚©‚ÌŒŸ¸
133 */
134static bool_t
135on_stack(void *addr, const TINIB *p_tinib)
136{
137 if (p_tinib->stk <= addr
138 && addr < (void *)((char *)(p_tinib->stk) + p_tinib->stksz)) {
139 return(true);
140 }
141 return(false);
142}
143
144/*
145 * ƒ^ƒXƒN–ˆ‚̐®‡«ŒŸ¸
146 */
147static ER
148bit_task(ID tskid)
149{
150 TCB *p_tcb;
151 const TINIB *p_tinib;
152 uint_t tstat, tstat_wait, priority;
153 TMEVTB *p_tmevtb;
154 SEMCB *p_semcb;
155 FLGCB *p_flgcb;
156 DTQCB *p_dtqcb;
157 PDQCB *p_pdqcb;
158 MBXCB *p_mbxcb;
159 MPFCB *p_mpfcb;
160
161 if (!(TMIN_TSKID <= (tskid) && (tskid) <= tmax_tskid)) {
162 return(E_ID);
163 }
164 p_tcb = get_tcb(tskid);
165 p_tinib = p_tcb->p_tinib;
166 tstat = p_tcb->tstat;
167 tstat_wait = (tstat & TS_WAIT_MASK);
168 priority = p_tcb->priority;
169
170 /*
171 * ‰Šú‰»ƒuƒƒbƒN‚ւ̃|ƒCƒ“ƒ^‚ÌŒŸ¸
172 */
173 if (p_tinib != &(tinib_table[INDEX_TSK(tskid)])) {
174 return(E_SYS_LINENO);
175 }
176
177 /*
178 * tstat‚ÌŒŸ¸
179 */
180 switch (tstat & (TS_RUNNABLE | TS_WAITING | TS_SUSPENDED)) {
181 case TS_DORMANT:
182 if (tstat != TS_DORMANT) {
183 return(E_SYS_LINENO);
184 }
185 break;
186 case TS_RUNNABLE:
187 if (tstat != TS_RUNNABLE) {
188 return(E_SYS_LINENO);
189 }
190 break;
191 case TS_WAITING:
192 case (TS_WAITING | TS_SUSPENDED):
193 if (!(TS_WAIT_DLY <= tstat_wait && tstat_wait <= TS_WAIT_MPF)) {
194 return(E_SYS_LINENO);
195 }
196 if ((tstat & ~(TS_WAIT_MASK | TS_RUNNABLE | TS_WAITING | TS_SUSPENDED))
197 != 0U) {
198 return(E_SYS_LINENO);
199 }
200 break;
201 case TS_SUSPENDED:
202 if (tstat != TS_SUSPENDED) {
203 return(E_SYS_LINENO);
204 }
205 break;
206 default:
207 return(E_SYS_LINENO);
208 }
209
210 /*
211 * actque‚ÌŒŸ¸
212 */
213 if (TSTAT_DORMANT(tstat) && p_tcb->actque) {
214 return(E_SYS_LINENO);
215 }
216
217 /*
218 * ƒ^ƒXƒN—Dæ“x‚ÌŒŸ¸
219 */
220 if (priority >= TNUM_TPRI) {
221 return(E_SYS_LINENO);
222 }
223
224 /*
225 * texptn‚ÌŒŸ¸
226 */
227 if (p_tcb->p_tinib->texrtn == NULL && p_tcb->texptn != 0U) {
228 return(E_SYS_LINENO);
229 }
230
231 /*
232 * ‹xŽ~ó‘Ô‚É‚¨‚¯‚éƒ`ƒFƒbƒN
233 */
234 if (TSTAT_DORMANT(tstat)) {
235 if (!(priority == p_tinib->ipriority)
236 && (p_tcb->wupque == false)
237 && (p_tcb->enatex == false)
238 && (p_tcb->texptn == 0U)) {
239 return(E_SYS_LINENO);
240 }
241 }
242
243 /*
244 * ŽÀs‚Å‚«‚éó‘Ô‚É‚¨‚¯‚éƒ`ƒFƒbƒN
245 */
246 if (TSTAT_RUNNABLE(tstat)) {
247 if (!in_queue(&ready_queue[priority], &(p_tcb->task_queue))) {
248 return(E_SYS_LINENO);
249 }
250 }
251
252 /*
253 * ‘Ò‚¿ó‘Ô‚É‚¨‚¯‚éƒ`ƒFƒbƒN
254 */
255 if (TSTAT_WAITING(tstat)) {
256 if (!on_stack(p_tcb->p_winfo, p_tinib)) {
257 return(E_SYS_LINENO);
258 }
259 p_tmevtb = p_tcb->p_winfo->p_tmevtb;
260 if (p_tmevtb != NULL) {
261 if (!on_stack(p_tmevtb, p_tinib)) {
262 return(E_SYS_LINENO);
263 }
264 /*
265 * (*p_tmevtb)‚ÌŒŸ¸i–¢Š®¬j
266 */
267 }
268
269 switch (tstat & TS_WAIT_MASK) {
270 case TS_WAIT_SLP:
271 if (p_tcb->wupque == true) {
272 return(E_SYS_LINENO);
273 }
274 break;
275
276 case TS_WAIT_DLY:
277 if (p_tmevtb == NULL) {
278 return(E_SYS_LINENO);
279 }
280 break;
281
282 case TS_WAIT_SEM:
283 p_semcb = ((WINFO_SEM *)(p_tcb->p_winfo))->p_semcb;
284 if (!VALID_SEMCB(p_semcb)) {
285 return(E_SYS_LINENO);
286 }
287 if (!in_queue(&(p_semcb->wait_queue), &(p_tcb->task_queue))) {
288 return(E_SYS_LINENO);
289 }
290 break;
291
292 case TS_WAIT_FLG:
293 p_flgcb = ((WINFO_FLG *)(p_tcb->p_winfo))->p_flgcb;
294 if (!VALID_FLGCB(p_flgcb)) {
295 return(E_SYS_LINENO);
296 }
297 if (!in_queue(&(p_flgcb->wait_queue), &(p_tcb->task_queue))) {
298 return(E_SYS_LINENO);
299 }
300 break;
301
302 case TS_WAIT_SDTQ:
303 p_dtqcb = ((WINFO_DTQ *)(p_tcb->p_winfo))->p_dtqcb;
304 if (!VALID_DTQCB(p_dtqcb)) {
305 return(E_SYS_LINENO);
306 }
307 if (!in_queue(&(p_dtqcb->swait_queue), &(p_tcb->task_queue))) {
308 return(E_SYS_LINENO);
309 }
310 break;
311
312 case TS_WAIT_RDTQ:
313 p_dtqcb = ((WINFO_DTQ *)(p_tcb->p_winfo))->p_dtqcb;
314 if (!VALID_DTQCB(p_dtqcb)) {
315 return(E_SYS_LINENO);
316 }
317 if (!in_queue(&(p_dtqcb->rwait_queue), &(p_tcb->task_queue))) {
318 return(E_SYS_LINENO);
319 }
320 break;
321
322 case TS_WAIT_SPDQ:
323 p_pdqcb = ((WINFO_PDQ *)(p_tcb->p_winfo))->p_pdqcb;
324 if (!VALID_PDQCB(p_pdqcb)) {
325 return(E_SYS_LINENO);
326 }
327 if (!in_queue(&(p_pdqcb->swait_queue), &(p_tcb->task_queue))) {
328 return(E_SYS_LINENO);
329 }
330 break;
331
332 case TS_WAIT_RPDQ:
333 p_pdqcb = ((WINFO_PDQ *)(p_tcb->p_winfo))->p_pdqcb;
334 if (!VALID_PDQCB(p_pdqcb)) {
335 return(E_SYS_LINENO);
336 }
337 if (!in_queue(&(p_pdqcb->rwait_queue), &(p_tcb->task_queue))) {
338 return(E_SYS_LINENO);
339 }
340 break;
341
342 case TS_WAIT_MBX:
343 p_mbxcb = ((WINFO_MBX *)(p_tcb->p_winfo))->p_mbxcb;
344 if (!VALID_MBXCB(p_mbxcb)) {
345 return(E_SYS_LINENO);
346 }
347 if (!in_queue(&(p_mbxcb->wait_queue), &(p_tcb->task_queue))) {
348 return(E_SYS_LINENO);
349 }
350 break;
351
352 case TS_WAIT_MPF:
353 p_mpfcb = ((WINFO_MPF *)(p_tcb->p_winfo))->p_mpfcb;
354 if (!VALID_MPFCB(p_mpfcb)) {
355 return(E_SYS_LINENO);
356 }
357 if (!in_queue(&(p_mpfcb->wait_queue), &(p_tcb->task_queue))) {
358 return(E_SYS_LINENO);
359 }
360 break;
361 }
362 }
363
364 /*
365 * tskctxb‚ÌŒŸ¸
366 */
367 if (!TSTAT_DORMANT(tstat) && p_tcb != p_runtsk) {
368 /*
369 * ƒ^[ƒQƒbƒgˆË‘¶‚ÌŒŸ¸
370 */
371#if 0
372 if (bit_tskctxb(&(p_tcb->tskctxb))) {
373 return(E_SYS_LINENO);
374 }
375#endif
376 }
377 return(E_OK);
378}
379
380/*
381 * ƒZƒ}ƒtƒH–ˆ‚̐®‡«ŒŸ¸
382 */
383#define INDEX_SEM(semid) ((uint_t)((semid) - TMIN_SEMID))
384#define get_semcb(semid) (&(semcb_table[INDEX_SEM(semid)]))
385
386static ER
387bit_semaphore(ID semid)
388{
389 SEMCB *p_semcb;
390 const SEMINIB *p_seminib;
391 uint_t semcnt;
392 QUEUE *p_queue;
393 TCB *p_tcb;
394
395 if (!(TMIN_SEMID <= (semid) && (semid) <= tmax_semid)) {
396 return(E_ID);
397 }
398 p_semcb = get_semcb(semid);
399 p_seminib = p_semcb->p_seminib;
400 semcnt = p_semcb->semcnt;
401
402 /*
403 * ‰Šú‰»ƒuƒƒbƒN‚ւ̃|ƒCƒ“ƒ^‚ÌŒŸ¸
404 */
405 if (p_seminib != &(seminib_table[INDEX_SEM(semid)])) {
406 return(E_SYS_LINENO);
407 }
408
409 /*
410 * semcnt‚ÌŒŸ¸
411 */
412 if (semcnt > p_seminib->maxsem) {
413 return(E_SYS_LINENO);
414 }
415
416 /*
417 * wait_queue‚ÌŒŸ¸
418 */
419 if (semcnt == 0) {
420 p_queue = p_semcb->wait_queue.p_next;
421 while (p_queue != &(p_semcb->wait_queue)) {
422 p_tcb = (TCB *) p_queue;
423 p_queue = p_queue->p_next;
424 if (!VALID_TCB(p_tcb)) {
425 return(E_SYS_LINENO);
426 }
427 if (p_tcb->tstat != (TS_WAITING | TS_WAIT_SEM)) {
428 return(E_SYS_LINENO);
429 }
430 if (p_semcb != ((WINFO_SEM *)(p_tcb->p_winfo))->p_semcb) {
431 return(E_SYS_LINENO);
432 }
433 }
434 }
435 else {
436 if (!queue_empty(&(p_semcb->wait_queue))) {
437 return(E_SYS_LINENO);
438 }
439 }
440 return(E_OK);
441}
442
443/*
444 * ®‡«ŒŸ¸ƒ‹[ƒ`ƒ“–{‘Ì
445 */
446ER
447bit_kernel(void)
448{
449 ID tskid;
450 ID semid;
451 ER ercd;
452
453 /*
454 * ƒ^ƒXƒN–ˆ‚ÌŒŸ¸
455 */
456 for (tskid = TMIN_TSKID; tskid <= tmax_tskid; tskid++) {
457 ercd = bit_task(tskid);
458 if (ercd != E_OK) {
459 return(ercd);
460 }
461 }
462
463 /*
464 * ƒZƒ}ƒtƒH–ˆ‚ÌŒŸ¸
465 */
466 for (semid = TMIN_SEMID; semid <= tmax_semid; semid++) {
467 ercd = bit_semaphore(semid);
468 if (ercd != E_OK) {
469 return(ercd);
470 }
471 }
472
473 return(E_OK);
474}
Note: See TracBrowser for help on using the repository browser.