source: asp3_wo_tecs/trunk/extension/messagebuf/test/bit_kernel.c@ 306

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

3.1.0を反映

File size: 15.0 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-2016 by Embedded and Real-Time Systems Laboratory
7 * Graduate School of Information Science, Nagoya Univ., JAPAN
8 *
9 * 上記著作権者
10は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
11 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
12 * 変・再é…
13å¸ƒï¼ˆä»¥ä¸‹ï¼Œåˆ©ç”¨ã¨å‘¼ã¶ï¼‰ã™ã‚‹ã“とを無償で許諾する.
14 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
15 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
16 * スコード中に含まれていること.
17 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
18 * 用できる形で再é…
19å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
20å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
21 * 者
22マニュアルなど)に,上記の著作権表示,この利用条件および下記
23 * の無保証規定を掲載すること.
24 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
25 * 用できない形で再é…
26å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
27 * と.
28 * (a) 再é…
29å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
30マニュアルなど)に,上記の著
31 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
32 * (b) 再é…
33å¸ƒã®å½¢æ…
34‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
35 * 報告すること.
36 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
37 * 害からも,上記著作権者
38およびTOPPERSプロジェクトをå…
39è²¬ã™ã‚‹ã“と.
40 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
41 * 由に基づく請求からも,上記著作権者
42およびTOPPERSプロジェクトを
43 * å…
44è²¬ã™ã‚‹ã“と.
45 *
46 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者
47お
48 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
49 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
50 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
51 * の責任を負わない.
52 *
53 * $Id: bit_kernel.c 741 2016-04-05 15:51:59Z ertl-hiro $
54 */
55
56/*
57 * カーネルの整合性検査
58 */
59
60#include "kernel/kernel_impl.h"
61#include "kernel/task.h"
62#include "kernel/wait.h"
63#include "kernel/semaphore.h"
64#include "kernel/eventflag.h"
65#include "kernel/dataqueue.h"
66#include "kernel/pridataq.h"
67#include "kernel/mutex.h"
68#include "kernel/messagebuf.h"
69#include "kernel/mempfix.h"
70#include "kernel/time_event.h"
71#include "kernel/check.h"
72
73/*
74 * エラーコードの定義
75 */
76#define E_SYS_LINENO ERCD(E_SYS, -(__LINE__))
77
78/*
79 * 管理ブロックのアドレスの正当性のチェック
80 */
81#define VALID_TCB(p_tcb) \
82 ((((char *) p_tcb) - ((char *) tcb_table)) % sizeof(TCB) == 0 \
83 && TMIN_TSKID <= TSKID(p_tcb) && TSKID(p_tcb) <= tmax_tskid)
84
85#define VALID_SEMCB(p_semcb) \
86 ((((char *) p_semcb) - ((char *) semcb_table)) % sizeof(SEMCB) == 0 \
87 && TMIN_SEMID <= SEMID(p_semcb) && SEMID(p_semcb) <= tmax_semid)
88
89#define VALID_FLGCB(p_flgcb) \
90 ((((char *) p_flgcb) - ((char *) flgcb_table)) % sizeof(FLGCB) == 0 \
91 && TMIN_FLGID <= FLGID(p_flgcb) && FLGID(p_flgcb) <= tmax_flgid)
92
93#define VALID_DTQCB(p_dtqcb) \
94 ((((char *) p_dtqcb) - ((char *) dtqcb_table)) % sizeof(DTQCB) == 0 \
95 && TMIN_DTQID <= DTQID(p_dtqcb) && DTQID(p_dtqcb) <= tmax_dtqid)
96
97#define VALID_PDQCB(p_pdqcb) \
98 ((((char *) p_pdqcb) - ((char *) pdqcb_table)) % sizeof(PDQCB) == 0 \
99 && TMIN_PDQID <= PDQID(p_pdqcb) && PDQID(p_pdqcb) <= tmax_pdqid)
100
101#define VALID_MTXCB(p_mtxcb) \
102 ((((char *) p_mtxcb) - ((char *) mtxcb_table)) % sizeof(MTXCB) == 0 \
103 && TMIN_MTXID <= MTXID(p_mtxcb) && MTXID(p_mtxcb) <= tmax_mtxid)
104
105#define VALID_MBFCB(p_mbfcb) \
106 ((((char *) p_mbfcb) - ((char *) mbfcb_table)) % sizeof(MBFCB) == 0 \
107 && TMIN_MBFID <= MBFID(p_mbfcb) && MBFID(p_mbfcb) <= tmax_mbfid)
108
109#define VALID_MPFCB(p_mpfcb) \
110 ((((char *) p_mpfcb) - ((char *) mpfcb_table)) % sizeof(MPFCB) == 0 \
111 && TMIN_MPFID <= MPFID(p_mpfcb) && MPFID(p_mpfcb) <= tmax_mpfid)
112
113/*
114 * キューのチェックのための関数
115 *
116 * p_queueにp_entryが含まれているかを調べる.含まれていればtrue,含ま
117 * れていない場合にはfalseを返す.ダブルリンクの不整合の場合にも,
118 * falseを返す.
119 */
120static bool_t
121in_queue(QUEUE *p_queue, QUEUE *p_entry)
122{
123 QUEUE *p_current, *p_next;
124
125 p_current = p_queue->p_next;
126 if (p_current->p_prev != p_queue) {
127 return(false); /* ダブルリンクの不整合 */
128 }
129 while (p_current != p_queue) {
130 if (p_current == p_entry) {
131 return(true); /* p_entryが含まれていた */
132 }
133
134 /*
135 * キューの次の要素に進む
136 */
137 p_next = p_current->p_next;
138 if (p_next->p_prev != p_current) {
139 return(false); /* ダブルリンクの不整合 */
140 }
141 p_current = p_next;
142 }
143 return(false);
144}
145
146/*
147 * スタック上を指しているかの検査
148 */
149static bool_t
150on_stack(void *addr, const TINIB *p_tinib)
151{
152#ifdef USE_TSKINICTXB
153 /*
154 * この関数の実装
155はターゲット依存になる.
156 */
157 return(true);
158#else /* USE_TSKINICTXB */
159 if (p_tinib->stk <= addr
160 && addr < (void *)((char *)(p_tinib->stk) + p_tinib->stksz)) {
161 return(true);
162 }
163 return(false);
164#endif /* USE_TSKINICTXB */
165}
166
167/*
168 * スケジューリングのためのデータ構造の検査
169 */
170#ifndef PRIMAP_BIT
171#define PRIMAP_BIT(pri) (1U << (pri))
172#endif /* PRIMAP_BIT */
173
174Inline bool_t
175primap_empty(void)
176{
177#ifndef PRIMAP_LEVEL_2
178 return(ready_primap == 0U);
179#else /* PRIMAP_LEVEL_2 */
180 return(ready_primap1 == 0U);
181#endif /* PRIMAP_LEVEL_2 */
182}
183
184Inline uint16_t
185primap_extract_bit(uint_t pri)
186{
187#ifndef PRIMAP_LEVEL_2
188 return(ready_primap & PRIMAP_BIT(pri));
189#else /* PRIMAP_LEVEL_2 */
190 return(ready_primap2[pri / TBIT_PRIMAP] & PRIMAP_BIT(pri % TBIT_PRIMAP));
191#endif /* PRIMAP_LEVEL_2 */
192}
193
194static ER
195bit_schedcb(void)
196{
197 uint_t pri;
198 QUEUE *p_queue;
199 TCB *p_tcb;
200
201 /*
202 * dspflgとp_schedtskの整合性の検査
203 */
204 if (dspflg) {
205 if (primap_empty()) {
206 if (p_schedtsk != NULL) {
207 return(E_SYS_LINENO);
208 }
209 }
210 else {
211 if (p_schedtsk != search_schedtsk()) {
212 return(E_SYS_LINENO);
213 }
214 }
215 }
216
217#ifdef PRIMAP_LEVEL_2
218 /*
219 * ready_primap1とready_primap2の整合性の検査
220 */
221 for (pri = 0; pri < TNUM_TPRI; pri += TBIT_PRIMAP) {
222 if (ready_primap2[pri / TBIT_PRIMAP] == 0U) {
223 if ((ready_primap1 & PRIMAP_BIT(pri / TBIT_PRIMAP)) != 0U) {
224 return(E_SYS_LINENO);
225 }
226 }
227 else {
228 if ((ready_primap1 & PRIMAP_BIT(pri / TBIT_PRIMAP)) == 0U) {
229 return(E_SYS_LINENO);
230 }
231 }
232 }
233#endif /* PRIMAP_LEVEL_2 */
234
235 /*
236 * ready_queueとready_primapの整合性の検査
237 */
238 for (pri = 0; pri < TNUM_TPRI; pri++) {
239 p_queue = ready_queue[pri].p_next;
240 if (p_queue == &ready_queue[pri]) {
241 if (primap_extract_bit(pri) != 0U) {
242 return(E_SYS_LINENO);
243 }
244 }
245 else {
246 if (primap_extract_bit(pri) == 0U) {
247 return(E_SYS_LINENO);
248 }
249 }
250 while (p_queue != &ready_queue[pri]) {
251 p_tcb = (TCB *) p_queue;
252 if (!VALID_TCB(p_tcb)) {
253 return(E_SYS_LINENO);
254 }
255 if (!TSTAT_RUNNABLE(p_tcb->tstat)) {
256 return(E_SYS_LINENO);
257 }
258 if (p_tcb->priority != pri) {
259 return(E_SYS_LINENO);
260 }
261 p_queue = p_queue->p_next;
262 }
263 }
264 return(E_OK);
265}
266
267/*
268 * タスク毎の整合性検査
269 */
270static ER
271bit_task(ID tskid)
272{
273 TCB *p_tcb;
274 const TINIB *p_tinib;
275 uint_t tstat, bpri, pri;
276 TMEVTB *p_tmevtb;
277 SEMCB *p_semcb;
278 FLGCB *p_flgcb;
279 DTQCB *p_dtqcb;
280 PDQCB *p_pdqcb;
281 MTXCB *p_mtxcb;
282 MBFCB *p_mbfcb;
283 MPFCB *p_mpfcb;
284
285 if (!VALID_TSKID(tskid)) {
286 return(E_ID);
287 }
288 p_tcb = get_tcb(tskid);
289 p_tinib = p_tcb->p_tinib;
290 tstat = p_tcb->tstat;
291 bpri = p_tcb->bpriority;
292 pri = p_tcb->priority;
293
294 /*
295 * タスク初期化ブロックへのポインタの検査
296 */
297 if (p_tinib != &(tinib_table[INDEX_TSK(tskid)])) {
298 return(E_SYS_LINENO);
299 }
300
301 /*
302 * tstatの検査
303 */
304 if (TSTAT_DORMANT(tstat)) {
305 if (tstat != TS_DORMANT) {
306 return(E_SYS_LINENO);
307 }
308 }
309 else if (TSTAT_WAITING(tstat)) {
310 if ((tstat & ~(TS_WAITING_MASK | TS_SUSPENDED)) != 0U) {
311 return(E_SYS_LINENO);
312 }
313 }
314 else if (TSTAT_SUSPENDED(tstat)) {
315 if (tstat != TS_SUSPENDED) {
316 return(E_SYS_LINENO);
317 }
318 }
319 else {
320 if (tstat != TS_RUNNABLE) {
321 return(E_SYS_LINENO);
322 }
323 }
324
325 /*
326 * ベース優å…
327ˆåº¦ã®æ¤œæŸ»
328 */
329 if (bpri >= TNUM_TPRI) {
330 return(E_SYS_LINENO);
331 }
332
333 /*
334 * 現在の優å…
335ˆåº¦ã®æ¤œæŸ»
336 */
337 if (pri > bpri) {
338 return(E_SYS_LINENO);
339 }
340
341 /*
342 * rasterと他の状æ…
343‹ã®æ•´åˆæ€§ã®æ¤œæŸ»
344 */
345 if (p_tcb->raster && (p_tcb->enater || TSTAT_WAITING(tstat))) {
346 return(E_SYS_LINENO);
347 }
348
349 /*
350 * 休止状æ…
351‹ã«ãŠã‘るチェック
352 */
353 if (TSTAT_DORMANT(tstat)) {
354 if (!(bpri == p_tinib->ipriority
355 && pri == p_tinib->ipriority
356 && p_tcb->actque == false
357 && p_tcb->wupque == false
358 && p_tcb->raster == false
359 && p_tcb->enater == true
360 && p_tcb->p_lastmtx == NULL)) {
361 return(E_SYS_LINENO);
362 }
363 }
364
365 /*
366 * 実行できる状æ…
367‹ã«ãŠã‘るチェック
368 */
369 if (TSTAT_RUNNABLE(tstat)) {
370 if (!in_queue(&ready_queue[pri], &(p_tcb->task_queue))) {
371 return(E_SYS_LINENO);
372 }
373 }
374
375 /*
376 * 待
377ち状æ…
378‹ã«ãŠã‘るチェック
379 */
380 if (TSTAT_WAITING(tstat)) {
381 if (!on_stack(p_tcb->p_winfo, p_tinib)) {
382 return(E_SYS_LINENO);
383 }
384 p_tmevtb = p_tcb->p_winfo->p_tmevtb;
385 if (p_tmevtb != NULL) {
386 if (!on_stack(p_tmevtb, p_tinib)) {
387 return(E_SYS_LINENO);
388 }
389 /*
390 * (*p_tmevtb)の検査(未完成)
391 */
392 }
393
394 switch (tstat & TS_WAITING_MASK) {
395 case TS_WAITING_SLP:
396 if (p_tcb->wupque == true) {
397 return(E_SYS_LINENO);
398 }
399 break;
400
401 case TS_WAITING_DLY:
402 if (p_tmevtb == NULL) {
403 return(E_SYS_LINENO);
404 }
405 break;
406
407 case TS_WAITING_SEM:
408 p_semcb = ((WINFO_SEM *)(p_tcb->p_winfo))->p_semcb;
409 if (!VALID_SEMCB(p_semcb)) {
410 return(E_SYS_LINENO);
411 }
412 if (!in_queue(&(p_semcb->wait_queue), &(p_tcb->task_queue))) {
413 return(E_SYS_LINENO);
414 }
415 break;
416
417 case TS_WAITING_FLG:
418 p_flgcb = ((WINFO_FLG *)(p_tcb->p_winfo))->p_flgcb;
419 if (!VALID_FLGCB(p_flgcb)) {
420 return(E_SYS_LINENO);
421 }
422 if (!in_queue(&(p_flgcb->wait_queue), &(p_tcb->task_queue))) {
423 return(E_SYS_LINENO);
424 }
425 break;
426
427 case TS_WAITING_SDTQ:
428 p_dtqcb = ((WINFO_SDTQ *)(p_tcb->p_winfo))->p_dtqcb;
429 if (!VALID_DTQCB(p_dtqcb)) {
430 return(E_SYS_LINENO);
431 }
432 if (!in_queue(&(p_dtqcb->swait_queue), &(p_tcb->task_queue))) {
433 return(E_SYS_LINENO);
434 }
435 break;
436
437 case TS_WAITING_RDTQ:
438 p_dtqcb = ((WINFO_RDTQ *)(p_tcb->p_winfo))->p_dtqcb;
439 if (!VALID_DTQCB(p_dtqcb)) {
440 return(E_SYS_LINENO);
441 }
442 if (!in_queue(&(p_dtqcb->rwait_queue), &(p_tcb->task_queue))) {
443 return(E_SYS_LINENO);
444 }
445 break;
446
447 case TS_WAITING_SPDQ:
448 p_pdqcb = ((WINFO_SPDQ *)(p_tcb->p_winfo))->p_pdqcb;
449 if (!VALID_PDQCB(p_pdqcb)) {
450 return(E_SYS_LINENO);
451 }
452 if (!in_queue(&(p_pdqcb->swait_queue), &(p_tcb->task_queue))) {
453 return(E_SYS_LINENO);
454 }
455 break;
456
457 case TS_WAITING_RPDQ:
458 p_pdqcb = ((WINFO_RPDQ *)(p_tcb->p_winfo))->p_pdqcb;
459 if (!VALID_PDQCB(p_pdqcb)) {
460 return(E_SYS_LINENO);
461 }
462 if (!in_queue(&(p_pdqcb->rwait_queue), &(p_tcb->task_queue))) {
463 return(E_SYS_LINENO);
464 }
465 break;
466
467 case TS_WAITING_MTX:
468 p_mtxcb = ((WINFO_MTX *)(p_tcb->p_winfo))->p_mtxcb;
469 if (!VALID_MTXCB(p_mtxcb)) {
470 return(E_SYS_LINENO);
471 }
472 if (!in_queue(&(p_mtxcb->wait_queue), &(p_tcb->task_queue))) {
473 return(E_SYS_LINENO);
474 }
475 break;
476
477 case TS_WAITING_SMBF:
478 p_mbfcb = ((WINFO_SMBF *)(p_tcb->p_winfo))->p_mbfcb;
479 if (!VALID_MBFCB(p_mbfcb)) {
480 return(E_SYS_LINENO);
481 }
482 if (!in_queue(&(p_mbfcb->swait_queue), &(p_tcb->task_queue))) {
483 return(E_SYS_LINENO);
484 }
485 break;
486
487 case TS_WAITING_RMBF:
488 p_mbfcb = ((WINFO_RMBF *)(p_tcb->p_winfo))->p_mbfcb;
489 if (!VALID_MBFCB(p_mbfcb)) {
490 return(E_SYS_LINENO);
491 }
492 if (!in_queue(&(p_mbfcb->rwait_queue), &(p_tcb->task_queue))) {
493 return(E_SYS_LINENO);
494 }
495 break;
496
497 case TS_WAITING_MPF:
498 p_mpfcb = ((WINFO_MPF *)(p_tcb->p_winfo))->p_mpfcb;
499 if (!VALID_MPFCB(p_mpfcb)) {
500 return(E_SYS_LINENO);
501 }
502 if (!in_queue(&(p_mpfcb->wait_queue), &(p_tcb->task_queue))) {
503 return(E_SYS_LINENO);
504 }
505 break;
506
507 default:
508 return(E_SYS_LINENO);
509 break;
510 }
511 }
512
513 /*
514 * p_lastmtxの検査
515 */
516 if (p_tcb->p_lastmtx != NULL) {
517 if (!VALID_MTXCB(p_tcb->p_lastmtx)) {
518 return(E_SYS_LINENO);
519 }
520 }
521
522 /*
523 * tskctxbの検査
524 */
525 if (!TSTAT_DORMANT(tstat) && p_tcb != p_runtsk) {
526 /*
527 * ターゲット依存の検査
528 */
529#if 0
530 if (bit_tskctxb(&(p_tcb->tskctxb))) {
531 return(E_SYS_LINENO);
532 }
533#endif
534 }
535 return(E_OK);
536}
537
538/*
539 * セマフォ毎の整合性検査
540 */
541#define INDEX_SEM(semid) ((uint_t)((semid) - TMIN_SEMID))
542#define get_semcb(semid) (&(semcb_table[INDEX_SEM(semid)]))
543
544static ER
545bit_semaphore(ID semid)
546{
547 SEMCB *p_semcb;
548 const SEMINIB *p_seminib;
549 uint_t semcnt, pri;
550 QUEUE *p_queue;
551 TCB *p_tcb;
552
553 if (!VALID_SEMID(semid)) {
554 return(E_ID);
555 }
556 p_semcb = get_semcb(semid);
557 p_seminib = p_semcb->p_seminib;
558 semcnt = p_semcb->semcnt;
559
560 /*
561 * セマフォ初期化ブロックへのポインタの検査
562 */
563 if (p_seminib != &(seminib_table[INDEX_SEM(semid)])) {
564 return(E_SYS_LINENO);
565 }
566
567 /*
568 * semcntの検査
569 */
570 if (semcnt > p_seminib->maxsem) {
571 return(E_SYS_LINENO);
572 }
573
574 /*
575 * wait_queueの検査
576 */
577 if (semcnt == 0) {
578 p_queue = p_semcb->wait_queue.p_next;
579 pri = TMIN_TPRI;
580 while (p_queue != &(p_semcb->wait_queue)) {
581 p_tcb = (TCB *) p_queue;
582 if (!VALID_TCB(p_tcb)) {
583 return(E_SYS_LINENO);
584 }
585
586 /*
587 * キューがタスク優å…
588ˆåº¦é †ã«ãªã£ã¦ã„るかの検査
589 */
590 if ((p_seminib->sematr & TA_TPRI) != 0U) {
591 if (p_tcb->priority < pri) {
592 return(E_SYS_LINENO);
593 }
594 }
595 pri = p_tcb->priority;
596
597 /*
598 * タスク状æ…
599‹ã®æ¤œæŸ»
600 */
601 if (p_tcb->tstat != TS_WAITING_SEM) {
602 return(E_SYS_LINENO);
603 }
604 if (p_semcb != ((WINFO_SEM *)(p_tcb->p_winfo))->p_semcb) {
605 return(E_SYS_LINENO);
606 }
607 p_queue = p_queue->p_next;
608 }
609 }
610 else {
611 if (!queue_empty(&(p_semcb->wait_queue))) {
612 return(E_SYS_LINENO);
613 }
614 }
615 return(E_OK);
616}
617
618/*
619 * 整合性検査ルーチン本体
620 */
621ER
622bit_kernel(void)
623{
624 ID tskid;
625 ID semid;
626 ER ercd;
627
628 /*
629 * スケジューリングのためのデータ構造の検査
630 */
631 ercd = bit_schedcb();
632 if (ercd != E_OK) {
633 return(ercd);
634 }
635
636 /*
637 * タスク毎の検査
638 */
639 for (tskid = TMIN_TSKID; tskid <= tmax_tskid; tskid++) {
640 ercd = bit_task(tskid);
641 if (ercd != E_OK) {
642 return(ercd);
643 }
644 }
645
646 /*
647 * セマフォ毎の検査
648 */
649 for (semid = TMIN_SEMID; semid <= tmax_semid; semid++) {
650 ercd = bit_semaphore(semid);
651 if (ercd != E_OK) {
652 return(ercd);
653 }
654 }
655
656 return(E_OK);
657}
Note: See TracBrowser for help on using the repository browser.