source: test/bit_kernel.c @ 7

このファイルの 7 以降における最終更新内容7 で kominami が 2015/09/12 9:22:12 に更新しました

TOPPERS/ASP 1.9.1

ファイルサイズ: 10.8 KB
Rev 
[7]1/*
2 *  TOPPERS/ASP Kernel
3 *      Toyohashi Open Platform for Embedded Real-Time Systems/
4 *      Advanced Standard Profile Kernel
5 *
6 *  Copyright (C) 2005-2011 by Embedded and Real-Time Systems Laboratory
7 *              Graduate School of Information Science, Nagoya Univ., JAPAN
8 *
9 *  Ÿåµ­Ãøºîž¢ŒÔ€Ï¡€°Ê²Œ€Î(1)¡Á(4)€ÎŸò·ï€òËþ€¿€¹Ÿì¹ç€ËžÂ€ê¡€ËÜ¥œ¥Õ¥È¥Š¥§
10 *  ¥¢¡ÊËÜ¥œ¥Õ¥È¥Š¥§¥¢€ò²þÊÑ€·€¿€â€Î€òŽÞ€à¡¥°Ê²ŒÆ±€ž¡Ë€ò»ÈÍÑ¡ŠÊ£Àœ¡Š²þ
11 *  ÊÑ¡ŠºÆÇÛÉۡʰʲŒ¡€ÍøÍрȞƀ֡ˀ¹€ë€³€È€ò̵œþ€ÇµöÂú€¹€ë¡¥
12 *  (1) ËÜ¥œ¥Õ¥È¥Š¥§¥¢€ò¥œ¡Œ¥¹¥³¡Œ¥É€Î·Á€ÇÍøÍÑ€¹€ëŸì¹ç€Ë€Ï¡€Ÿåµ­€ÎÃøºî
13 *      ž¢ÉœŒš¡€€³€ÎÍøÍÑŸò·ï€ª€è€Ó²Œµ­€Î̵ÊÝŸÚµ¬Äꀬ¡€€œ€Î€Þ€Þ€Î·Á€Ç¥œ¡Œ
14 *      ¥¹¥³¡Œ¥ÉÃæ€ËŽÞ€Þ€ì€Æ€€€ë€³€È¡¥
15 *  (2) ËÜ¥œ¥Õ¥È¥Š¥§¥¢€ò¡€¥é¥€¥Ö¥é¥ê·ÁŒ°€Ê€É¡€ÂŸ€Î¥œ¥Õ¥È¥Š¥§¥¢³«È¯€Ë»È
16 *      Íрǀ­€ë·Á€ÇºÆÇÛÉÛ€¹€ëŸì¹ç€Ë€Ï¡€ºÆÇÛÉÛ€ËÈŒ€Š¥É¥­¥å¥á¥ó¥È¡ÊÍøÍÑ
17 *      ŒÔ¥Þ¥Ë¥å¥¢¥ë€Ê€É¡Ë€Ë¡€Ÿåµ­€ÎÃøºîž¢ÉœŒš¡€€³€ÎÍøÍÑŸò·ï€ª€è€Ó²Œµ­
18 *      €Î̵ÊÝŸÚµ¬Äê€ò·ÇºÜ€¹€ë€³€È¡¥
19 *  (3) ËÜ¥œ¥Õ¥È¥Š¥§¥¢€ò¡€µ¡Žï€ËÁȀ߹þ€à€Ê€É¡€ÂŸ€Î¥œ¥Õ¥È¥Š¥§¥¢³«È¯€Ë»È
20 *      Íрǀ­€Ê€€·Á€ÇºÆÇÛÉÛ€¹€ëŸì¹ç€Ë€Ï¡€Œ¡€Î€€€º€ì€«€ÎŸò·ï€òËþ€¿€¹€³
21 *      €È¡¥
22 *    (a) ºÆÇÛÉÛ€ËÈŒ€Š¥É¥­¥å¥á¥ó¥È¡ÊÍøÍьԥޥ˥奢¥ë€Ê€É¡Ë€Ë¡€Ÿåµ­€ÎÃø
23 *        ºîž¢ÉœŒš¡€€³€ÎÍøÍÑŸò·ï€ª€è€Ó²Œµ­€Î̵ÊÝŸÚµ¬Äê€ò·ÇºÜ€¹€ë€³€È¡¥
24 *    (b) ºÆÇÛÉۀηÁÂÖ€ò¡€ÊÌ€ËÄê€á€ëÊýË¡€Ë€è€Ã€Æ¡€TOPPERS¥×¥í¥ž¥§¥¯¥È€Ë
25 *        Êó¹ð€¹€ë€³€È¡¥
26 *  (4) ËÜ¥œ¥Õ¥È¥Š¥§¥¢€ÎÍøÍрˀè€êÄŸÀÜŪ€Þ€¿€ÏŽÖÀÜŪ€ËÀž€ž€ë€€€«€Ê€ë»
27 *      ³²€«€é€â¡€Ÿåµ­Ãøºîž¢ŒÔ€ª€è€ÓTOPPERS¥×¥í¥ž¥§¥¯¥È€òÌÈÀÕ€¹€ë€³€È¡¥
28 *      €Þ€¿¡€ËÜ¥œ¥Õ¥È¥Š¥§¥¢€Î¥æ¡Œ¥¶€Þ€¿€Ï¥š¥ó¥É¥æ¡Œ¥¶€«€é€Î€€€«€Ê€ëÍý
29 *      ͳ€ËŽð€Å€¯ÀÁµá€«€é€â¡€Ÿåµ­Ãøºîž¢ŒÔ€ª€è€ÓTOPPERS¥×¥í¥ž¥§¥¯¥È€ò
30 *      ÌÈÀÕ€¹€ë€³€È¡¥
31 *
32 *  ËÜ¥œ¥Õ¥È¥Š¥§¥¢€Ï¡€ÌµÊÝŸÚ€ÇÄó¶¡€µ€ì€Æ€€€ë€â€Î€Ç€¢€ë¡¥Ÿåµ­Ãøºîž¢ŒÔ€ª
33 *  €è€ÓTOPPERS¥×¥í¥ž¥§¥¯¥È€Ï¡€ËÜ¥œ¥Õ¥È¥Š¥§¥¢€ËŽØ€·€Æ¡€ÆÃÄê€Î»ÈÍÑÌÜŪ
34 *  €ËÂЀ¹€ëŬ¹çÀ­€âŽÞ€á€Æ¡€€€€«€Ê€ëÊÝŸÚ€â¹Ô€ï€Ê€€¡¥€Þ€¿¡€ËÜ¥œ¥Õ¥È¥Š¥§
35 *  ¥¢€ÎÍøÍрˀè€êÄŸÀÜŪ€Þ€¿€ÏŽÖÀÜŪ€ËÀž€ž€¿€€€«€Ê€ë»³²€ËŽØ€·€Æ€â¡€€œ
36 *  €ÎÀÕÇ€€òÉé€ï€Ê€€¡¥
37 *
38 *  @(#) $Id$
39 */
40
41/*
42 *              ¥«¡Œ¥Í¥ë€ÎÀ°¹çÀ­ž¡ºº
43 */
44
45#include "kernel/kernel_impl.h"
46#include "kernel/task.h"
47#include "kernel/wait.h"
48#include "kernel/semaphore.h"
49#include "kernel/eventflag.h"
50#include "kernel/dataqueue.h"
51#include "kernel/pridataq.h"
52#include "kernel/mailbox.h"
53#include "kernel/mempfix.h"
54#include "kernel/time_event.h"
55
56/*
57 *   ¥š¥é¡Œ¥³¡Œ¥É€ÎÄêµÁ
58 */
59#define E_SYS_LINENO    ERCD(E_SYS, -(__LINE__))
60
61/*
62 *  ŽÉÍý¥Ö¥í¥Ã¥¯€Î¥¢¥É¥ì¥¹€ÎÀµÅöÀ­€Î¥Á¥§¥Ã¥¯
63 */
64#define VALID_TCB(p_tcb) \
65                ((((char *) p_tcb) - ((char *) tcb_table)) % sizeof(TCB) == 0 \
66                        && TMIN_TSKID <= TSKID(p_tcb) && TSKID(p_tcb) <= tmax_tskid)
67
68#define VALID_SEMCB(p_semcb) \
69                ((((char *) p_semcb) - ((char *) semcb_table)) % sizeof(SEMCB) == 0 \
70                        && TMIN_SEMID <= SEMID(p_semcb) && SEMID(p_semcb) <= tmax_semid)
71                               
72#define VALID_FLGCB(p_flgcb) \
73                ((((char *) p_flgcb) - ((char *) flgcb_table)) % sizeof(FLGCB) == 0 \
74                        && TMIN_FLGID <= FLGID(p_flgcb) && FLGID(p_flgcb) <= tmax_flgid)
75
76#define VALID_DTQCB(p_dtqcb) \
77                ((((char *) p_dtqcb) - ((char *) dtqcb_table)) % sizeof(DTQCB) == 0 \
78                        && TMIN_DTQID <= DTQID(p_dtqcb) && DTQID(p_dtqcb) <= tmax_dtqid)
79
80#define VALID_PDQCB(p_pdqcb) \
81                ((((char *) p_pdqcb) - ((char *) pdqcb_table)) % sizeof(PDQCB) == 0 \
82                        && TMIN_PDQID <= PDQID(p_pdqcb) && PDQID(p_pdqcb) <= tmax_pdqid)
83
84#define VALID_MBXCB(p_mbxcb) \
85                ((((char *) p_mbxcb) - ((char *) mbxcb_table)) % sizeof(MBXCB) == 0 \
86                        && TMIN_MBXID <= MBXID(p_mbxcb) && MBXID(p_mbxcb) <= tmax_mbxid)
87
88#define VALID_MPFCB(p_mpfcb) \
89                ((((char *) p_mpfcb) - ((char *) mpfcb_table)) % sizeof(MPFCB) == 0 \
90                        && TMIN_MPFID <= MPFID(p_mpfcb) && MPFID(p_mpfcb) <= tmax_mpfid)
91
92/*
93 *  ¥­¥å¡Œ€Î¥Á¥§¥Ã¥¯€Î€¿€á€ÎŽØ¿ô
94 *
95 *  p_queue€Ëp_entry€¬ŽÞ€Þ€ì€Æ€€€ë€«€òÄŽ€Ù€ë¡¥ŽÞ€Þ€ì€Æ€€€ì€Ðtrue¡€ŽÞ€Þ
96 *  €ì€Æ€€€Ê€€Ÿì¹ç€Ë€Ïfalse€òÊÖ€¹¡¥¥À¥Ö¥ë¥ê¥ó¥¯€ÎÉÔÀ°¹ç€ÎŸì¹ç€Ë€â¡€
97 *  false€òÊÖ€¹¡¥
98 */
99static bool_t
100in_queue(QUEUE *p_queue, QUEUE *p_entry)
101{
102        QUEUE   *p_current, *p_next;
103
104        p_current = p_queue->p_next;
105        if (p_current->p_prev != p_queue) {
106                return(false);                                  /* ¥À¥Ö¥ë¥ê¥ó¥¯€ÎÉÔÀ°¹ç */
107        }
108        while (p_current != p_queue) {
109                if (p_current == p_entry) {
110                        return(true);                           /* p_entry€¬ŽÞ€Þ€ì€Æ€€€¿ */
111                }
112
113                /*
114                 *  ¥­¥å¡Œ€ÎŒ¡€ÎÍ×Áǀ˿ʀà
115                 */
116                p_next = p_current->p_next;
117                if (p_next->p_prev != p_current) {
118                        return(false);                           /* ¥À¥Ö¥ë¥ê¥ó¥¯€ÎÉÔÀ°¹ç */
119                }
120                p_current = p_next;
121        }
122        return(false);
123}
124
125/*
126 *  ¥¹¥¿¥Ã¥¯Ÿå€ò»Ø€·€Æ€€€ë€«€Îž¡ºº
127 */
128static bool_t
129on_stack(void *addr, const TINIB *p_tinib)
130{
131        if (p_tinib->stk <= addr
132                                && addr < (void *)((char *)(p_tinib->stk) + p_tinib->stksz)) {
133                return(true);
134        }
135        return(false);
136}
137
138/*
139 *  ¥¿¥¹¥¯Ëè€ÎÀ°¹çÀ­ž¡ºº
140 */
141static ER
142bit_task(ID tskid)
143{
144        TCB                     *p_tcb;
145        const TINIB     *p_tinib;
146        uint_t          tstat, tstat_wait, pri;
147        TMEVTB          *p_tmevtb;
148        SEMCB           *p_semcb;
149        FLGCB           *p_flgcb;
150        DTQCB           *p_dtqcb;
151        PDQCB           *p_pdqcb;
152        MBXCB           *p_mbxcb;
153        MPFCB           *p_mpfcb;
154
155        if (!(TMIN_TSKID <= (tskid) && (tskid) <= tmax_tskid)) {
156                return(E_ID);
157        }
158        p_tcb = get_tcb(tskid);
159        p_tinib = p_tcb->p_tinib;
160        tstat = p_tcb->tstat;
161        tstat_wait = (tstat & TS_WAIT_MASK);
162        pri = p_tcb->priority;
163
164        /*
165         *  œéŽü²œ¥Ö¥í¥Ã¥¯€Ø€Î¥Ý¥€¥ó¥¿€Îž¡ºº
166         */
167        if (p_tinib != &(tinib_table[INDEX_TSK(tskid)])) {
168                return(E_SYS_LINENO);
169        }
170
171        /*
172         *  tstat€Îž¡ºº
173         */
174        switch (tstat & (TS_RUNNABLE | TS_WAITING | TS_SUSPENDED)) {
175        case TS_DORMANT:
176                if (tstat != TS_DORMANT) {
177                        return(E_SYS_LINENO);
178                }
179                break;
180        case TS_RUNNABLE:
181                if (tstat != TS_RUNNABLE) {
182                        return(E_SYS_LINENO);
183                }
184                break;
185        case TS_WAITING:
186        case (TS_WAITING | TS_SUSPENDED):
187                if (!(TS_WAIT_DLY <= tstat_wait && tstat_wait <= TS_WAIT_MPF)) {
188                        return(E_SYS_LINENO);
189                }
190                if ((tstat & ~(TS_WAIT_MASK | TS_RUNNABLE | TS_WAITING | TS_SUSPENDED))
191                                                                                                                                        != 0U) {
192                        return(E_SYS_LINENO);
193                }
194                break;
195        case TS_SUSPENDED:
196                if (tstat != TS_SUSPENDED) {
197                        return(E_SYS_LINENO);
198                }
199                break;
200        default:
201                return(E_SYS_LINENO);
202        }
203
204        /*
205         *  actque€Îž¡ºº
206         */
207        if (TSTAT_DORMANT(tstat) && p_tcb->actque) {
208                return(E_SYS_LINENO);
209        }
210
211        /*
212         *  ¥¿¥¹¥¯Í¥ÀèÅـΞ¡ºº
213         */
214        if (pri >= TNUM_TPRI) {
215                return(E_SYS_LINENO);
216        }
217
218        /*
219         *  texptn€Îž¡ºº
220         */
221        if (p_tcb->p_tinib->texrtn == NULL && p_tcb->texptn != 0U) {
222                return(E_SYS_LINENO);
223        }
224
225        /*
226         *  µÙ»ßŸõÂրˀª€±€ë¥Á¥§¥Ã¥¯
227         */
228        if (TSTAT_DORMANT(tstat)) {
229                if (!(pri == p_tinib->ipriority)
230                                        && (p_tcb->wupque == false)
231                                        && (p_tcb->enatex == false)
232                                        && (p_tcb->texptn == 0U)) {
233                        return(E_SYS_LINENO);
234                }
235        }
236
237        /*
238         *  ŒÂ¹Ô€Ç€­€ëŸõÂրˀª€±€ë¥Á¥§¥Ã¥¯
239         */
240        if (TSTAT_RUNNABLE(tstat)) {
241                if (!in_queue(&ready_queue[pri], &(p_tcb->task_queue))) {
242                        return(E_SYS_LINENO);
243                }
244        }
245
246        /*
247         *  ÂÔ€ÁŸõÂրˀª€±€ë¥Á¥§¥Ã¥¯
248         */
249        if (TSTAT_WAITING(tstat)) {
250                if (!on_stack(p_tcb->p_winfo, p_tinib)) {
251                        return(E_SYS_LINENO);
252                }
253                p_tmevtb = p_tcb->p_winfo->p_tmevtb;
254                if (p_tmevtb != NULL) {
255                        if (!on_stack(p_tmevtb, p_tinib)) {
256                                return(E_SYS_LINENO);
257                        }
258                        /*
259                         *  (*p_tmevtb)€Îž¡ºº¡ÊÌ€Ž°À®¡Ë
260                         */
261                }
262
263                switch (tstat & TS_WAIT_MASK) {
264                        case TS_WAIT_SLP:
265                                if (p_tcb->wupque == true) {
266                                        return(E_SYS_LINENO);
267                                }
268                                break;
269
270                        case TS_WAIT_DLY:
271                                if (p_tmevtb == NULL) {
272                                        return(E_SYS_LINENO);
273                                }
274                                break;
275
276                        case TS_WAIT_SEM:
277                                p_semcb = ((WINFO_SEM *)(p_tcb->p_winfo))->p_semcb;
278                                if (!VALID_SEMCB(p_semcb)) {
279                                        return(E_SYS_LINENO);
280                                }
281                                if (!in_queue(&(p_semcb->wait_queue), &(p_tcb->task_queue))) {
282                                        return(E_SYS_LINENO);
283                                }
284                                break;
285
286                        case TS_WAIT_FLG:
287                                p_flgcb = ((WINFO_FLG *)(p_tcb->p_winfo))->p_flgcb;
288                                if (!VALID_FLGCB(p_flgcb)) {
289                                        return(E_SYS_LINENO);
290                                }
291                                if (!in_queue(&(p_flgcb->wait_queue), &(p_tcb->task_queue))) {
292                                        return(E_SYS_LINENO);
293                                }
294                                break;
295
296                        case TS_WAIT_SDTQ:
297                                p_dtqcb = ((WINFO_DTQ *)(p_tcb->p_winfo))->p_dtqcb;
298                                if (!VALID_DTQCB(p_dtqcb)) {
299                                        return(E_SYS_LINENO);
300                                }
301                                if (!in_queue(&(p_dtqcb->swait_queue), &(p_tcb->task_queue))) {
302                                        return(E_SYS_LINENO);
303                                }
304                                break;
305
306                        case TS_WAIT_RDTQ:
307                                p_dtqcb = ((WINFO_DTQ *)(p_tcb->p_winfo))->p_dtqcb;
308                                if (!VALID_DTQCB(p_dtqcb)) {
309                                        return(E_SYS_LINENO);
310                                }
311                                if (!in_queue(&(p_dtqcb->rwait_queue), &(p_tcb->task_queue))) {
312                                        return(E_SYS_LINENO);
313                                }
314                                break;
315
316                        case TS_WAIT_SPDQ:
317                                p_pdqcb = ((WINFO_PDQ *)(p_tcb->p_winfo))->p_pdqcb;
318                                if (!VALID_PDQCB(p_pdqcb)) {
319                                        return(E_SYS_LINENO);
320                                }
321                                if (!in_queue(&(p_pdqcb->swait_queue), &(p_tcb->task_queue))) {
322                                        return(E_SYS_LINENO);
323                                }
324                                break;
325
326                        case TS_WAIT_RPDQ:
327                                p_pdqcb = ((WINFO_PDQ *)(p_tcb->p_winfo))->p_pdqcb;
328                                if (!VALID_PDQCB(p_pdqcb)) {
329                                        return(E_SYS_LINENO);
330                                }
331                                if (!in_queue(&(p_pdqcb->rwait_queue), &(p_tcb->task_queue))) {
332                                        return(E_SYS_LINENO);
333                                }
334                                break;
335
336                        case TS_WAIT_MBX:
337                                p_mbxcb = ((WINFO_MBX *)(p_tcb->p_winfo))->p_mbxcb;
338                                if (!VALID_MBXCB(p_mbxcb)) {
339                                        return(E_SYS_LINENO);
340                                }
341                                if (!in_queue(&(p_mbxcb->wait_queue), &(p_tcb->task_queue))) {
342                                        return(E_SYS_LINENO);
343                                }
344                                break;
345
346                        case TS_WAIT_MPF:
347                                p_mpfcb = ((WINFO_MPF *)(p_tcb->p_winfo))->p_mpfcb;
348                                if (!VALID_MPFCB(p_mpfcb)) {
349                                        return(E_SYS_LINENO);
350                                }
351                                if (!in_queue(&(p_mpfcb->wait_queue), &(p_tcb->task_queue))) {
352                                        return(E_SYS_LINENO);
353                                }
354                                break;
355                }
356        }
357
358        /*
359         *  tskctxb€Îž¡ºº
360         */
361        if (!TSTAT_DORMANT(tstat) && p_tcb != p_runtsk) {
362                /*
363                 *  ¥¿¡Œ¥²¥Ã¥È°Íž€Îž¡ºº
364                 */
365#if 0
366                if (bit_tskctxb(&(p_tcb->tskctxb))) {
367                        return(E_SYS_LINENO);
368                }
369#endif
370        }
371        return(E_OK);
372}
373
374/*
375 *  ¥»¥Þ¥Õ¥©Ëè€ÎÀ°¹çÀ­ž¡ºº
376 */
377#define INDEX_SEM(semid)        ((uint_t)((semid) - TMIN_SEMID))
378#define get_semcb(semid)        (&(semcb_table[INDEX_SEM(semid)]))
379
380static ER
381bit_semaphore(ID semid)
382{
383        SEMCB                   *p_semcb;
384        const SEMINIB   *p_seminib;
385        uint_t                  semcnt;
386        QUEUE                   *p_queue;
387        TCB                             *p_tcb;
388
389        if (!(TMIN_SEMID <= (semid) && (semid) <= tmax_semid)) {
390                return(E_ID);
391        }
392        p_semcb = get_semcb(semid);
393        p_seminib = p_semcb->p_seminib;
394        semcnt = p_semcb->semcnt;
395
396        /*
397         *  œéŽü²œ¥Ö¥í¥Ã¥¯€Ø€Î¥Ý¥€¥ó¥¿€Îž¡ºº
398         */
399        if (p_seminib != &(seminib_table[INDEX_SEM(semid)])) {
400                return(E_SYS_LINENO);
401        }
402
403        /*
404         *  semcnt€Îž¡ºº
405         */
406        if (semcnt > p_seminib->maxsem) {
407                return(E_SYS_LINENO);
408        }
409
410        /*
411         *  wait_queue€Îž¡ºº
412         */
413        if (semcnt == 0) {
414                p_queue = p_semcb->wait_queue.p_next;
415                while (p_queue != &(p_semcb->wait_queue)) {
416                        p_tcb = (TCB *) p_queue;
417                        p_queue = p_queue->p_next;
418                        if (!VALID_TCB(p_tcb)) {
419                                return(E_SYS_LINENO);
420                        }
421                        if (p_tcb->tstat != (TS_WAITING | TS_WAIT_SEM)) {
422                                return(E_SYS_LINENO);
423                        }
424                        if (p_semcb != ((WINFO_SEM *)(p_tcb->p_winfo))->p_semcb) {
425                                return(E_SYS_LINENO);
426                        }
427                }
428        }
429        else {
430                if (!queue_empty(&(p_semcb->wait_queue))) {
431                        return(E_SYS_LINENO);
432                }
433        }
434        return(E_OK);
435}
436
437/*
438 *  À°¹çÀ­ž¡ºº¥ë¡Œ¥Á¥óËÜÂÎ
439 */
440ER
441bit_kernel(void)
442{
443        ID              tskid;
444        ID              semid;
445        ER              ercd;
446
447        /*
448         *  ¥¿¥¹¥¯Ëè€Îž¡ºº
449         */
450        for (tskid = TMIN_TSKID; tskid <= tmax_tskid; tskid++) {
451                ercd = bit_task(tskid);
452                if (ercd != E_OK) {
453                        return(ercd);
454                }
455        }
456
457        /*
458         *  ¥»¥Þ¥Õ¥©Ëè€Îž¡ºº
459         */
460        for (semid = TMIN_SEMID; semid <= tmax_semid; semid++) {
461                ercd = bit_semaphore(semid);
462                if (ercd != E_OK) {
463                        return(ercd);
464                }
465        }
466
467        return(E_OK);
468}
詳しい使い方は TracBrowser を参照してください。