source: mypx/extension/mutex/test/bit_mutex.c @ 7

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

TOPPERS/ASP 1.9.1

ファイルサイズ: 7.9 KB
 
1/*
2 *  TOPPERS/ASP Kernel
3 *      Toyohashi Open Platform for Embedded Real-Time Systems/
4 *      High Reliable system 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/mutex.h"
48
49/*
50 *  ¥ß¥å¡Œ¥Æ¥Ã¥¯¥¹ID€«€é¥ß¥å¡Œ¥Æ¥Ã¥¯¥¹ŽÉÍý¥Ö¥í¥Ã¥¯€òŒè€êœÐ€¹€¿€á€Î¥Þ¥¯
51 *  ¥í¡Êmutex.c€è€ê¡Ë
52 */
53#define INDEX_MTX(mtxid)        ((uint_t)((mtxid) - TMIN_MTXID))
54#define get_mtxcb(mtxid)        (&(mtxcb_table[INDEX_MTX(mtxid)]))
55
56/*
57 *  ¥ß¥å¡Œ¥Æ¥Ã¥¯¥¹ŽÉÍý¥Ö¥í¥Ã¥¯Ãæ€Îmutex_queue€Ø€Î¥Ý¥€¥ó¥¿€«€é¡€¥ß¥å¡Œ¥Æ¥Ã
58 *  ¥¯¥¹ŽÉÍý¥Ö¥í¥Ã¥¯€Ø€Î¥Ý¥€¥ó¥¿€òŒè€êœÐ€¹€¿€á€Î¥Þ¥¯¥í¡Êmutex.c€è€ê¡Ë
59 */
60#define MTXCB_QUEUE(p_queue) \
61                        ((MTXCB *)(((char *) p_queue) - offsetof(MTXCB, mutex_queue)))
62
63/*
64 *  ¥ß¥å¡Œ¥Æ¥Ã¥¯¥¹€Î¥×¥í¥È¥³¥ë€òÈœÃÇ€¹€ë¥Þ¥¯¥í¡Êmutex.c€è€ê¡Ë
65 */
66#define MTXPROTO_MASK                   0x03U
67#define MTXPROTO(p_mtxcb)               ((p_mtxcb)->p_mtxinib->mtxatr & MTXPROTO_MASK)
68#define MTX_CEILING(p_mtxcb)    (MTXPROTO(p_mtxcb) == TA_CEILING)
69
70/*
71 *   ¥š¥é¡Œ¥³¡Œ¥É€ÎÄêµÁ
72 */
73#define E_SYS_LINENO    ERCD(E_SYS, -(__LINE__))
74
75/*
76 *  ŽÉÍý¥Ö¥í¥Ã¥¯€Î¥¢¥É¥ì¥¹€ÎÀµÅöÀ­€Î¥Á¥§¥Ã¥¯
77 */
78#define VALID_TCB(p_tcb) \
79                ((((char *) p_tcb) - ((char *) tcb_table)) % sizeof(TCB) == 0 \
80                        && TMIN_TSKID <= TSKID(p_tcb) && TSKID(p_tcb) <= tmax_tskid)
81
82#define VALID_MTXCB(p_mtxcb) \
83                ((((char *) p_mtxcb) - ((char *) mtxcb_table)) % sizeof(MTXCB) == 0 \
84                        && TMIN_MTXID <= MTXID(p_mtxcb) && MTXID(p_mtxcb) <= tmax_mtxid)
85                               
86/*
87 *  ¥­¥å¡Œ€Î¥Á¥§¥Ã¥¯€Î€¿€á€ÎŽØ¿ô
88 *
89 *  p_queue€Ëp_entry€¬ŽÞ€Þ€ì€Æ€€€ë€«€òÄŽ€Ù€ë¡¥ŽÞ€Þ€ì€Æ€€€ì€Ðtrue¡€ŽÞ€Þ
90 *  €ì€Æ€€€Ê€€Ÿì¹ç€Ë€Ïfalse€òÊÖ€¹¡¥¥À¥Ö¥ë¥ê¥ó¥¯€ÎÉÔÀ°¹ç€ÎŸì¹ç€Ë€â¡€
91 *  false€òÊÖ€¹¡¥
92 */
93static bool_t
94in_queue(QUEUE *p_queue, QUEUE *p_entry)
95{
96        QUEUE   *p_current, *p_next;
97
98        p_current = p_queue->p_next;
99        if (p_current->p_prev != p_queue) {
100                return(false);                                  /* ¥À¥Ö¥ë¥ê¥ó¥¯€ÎÉÔÀ°¹ç */
101        }
102        while (p_current != p_queue) {
103                if (p_current == p_entry) {
104                        return(true);                           /* p_entry€¬ŽÞ€Þ€ì€Æ€€€¿ */
105                }
106
107                /*
108                 *  ¥­¥å¡Œ€ÎŒ¡€ÎÍ×Áǀ˿ʀà
109                 */
110                p_next = p_current->p_next;
111                if (p_next->p_prev != p_current) {
112                        return(false);                           /* ¥À¥Ö¥ë¥ê¥ó¥¯€ÎÉÔÀ°¹ç */
113                }
114                p_current = p_next;
115        }
116        return(false);
117}
118
119/*
120 *  ¥¿¥¹¥¯Ëè€Îž¡ºº
121 */
122static ER
123bit_mutex_task(ID tskid)
124{
125        TCB                     *p_tcb;
126        MTXCB           *p_mtxcb;
127        QUEUE           *p_queue, *p_next;
128        uint_t          pri;
129
130        if (!(TMIN_TSKID <= (tskid) && (tskid) <= tmax_tskid)) {
131                return(E_ID);
132        }
133        p_tcb = get_tcb(tskid);
134        pri = p_tcb->bpriority;
135
136        /*
137         *  ¥¿¥¹¥¯€¬¥í¥Ã¥¯€·€Æ€€€ë¥ß¥å¡Œ¥Æ¥Ã¥¯¥¹€Î¥­¥å¡Œ€Îž¡ºº
138         */
139        p_queue = p_tcb->mutex_queue.p_next;
140        if (p_queue->p_prev != &(p_tcb->mutex_queue)) {
141                return(E_SYS_LINENO);
142        }
143        while (p_queue != &(p_tcb->mutex_queue)) {
144                p_mtxcb = MTXCB_QUEUE(p_queue);
145                if (!VALID_MTXCB(p_mtxcb)) {
146                        return(E_SYS_LINENO);
147                }
148
149                /*
150                 *  ¥ß¥å¡Œ¥Æ¥Ã¥¯¥¹€ò¥í¥Ã¥¯€·€Æ€€€ë¥¿¥¹¥¯€Î¥Á¥§¥Ã¥¯
151                 */
152                if (p_mtxcb->p_loctsk != p_tcb) {
153                        return(E_SYS_LINENO);
154                }
155
156                /*
157                 *  žœºßÍ¥ÀèÅـη׻»
158                 */
159                if (MTXPROTO(p_mtxcb)) {
160                        if (p_mtxcb->p_mtxinib->ceilpri < pri) {
161                                pri = p_mtxcb->p_mtxinib->ceilpri;
162                        }
163                }
164
165                /*
166                 *  ¥­¥å¡Œ€ÎŒ¡€ÎÍ×Áǀ˿ʀà
167                 */
168                p_next = p_queue->p_next;
169                if (p_next->p_prev != p_queue) {
170                        return(E_SYS_LINENO);
171                }
172                p_queue = p_next;
173        }
174
175        /*
176         *  žœºßÍ¥ÀèÅـΞ¡ºº
177         */
178        if (p_tcb->priority != pri) {
179                return(E_SYS_LINENO);
180        }
181
182        /*
183         *  ¥¿¥¹¥¯€¬ÂԀÀƀ€€ë¥ß¥å¡Œ¥Æ¥Ã¥¯¥¹€ËŽØ€¹€ëž¡ºº
184         */
185        if (TSTAT_WAIT_MTX(p_tcb->tstat)) {
186                p_mtxcb = ((WINFO_MTX *)(p_tcb->p_winfo))->p_mtxcb;
187                if (!VALID_MTXCB(p_mtxcb)) {
188                        return(E_SYS_LINENO);
189                }
190                if (!in_queue(&(p_mtxcb->wait_queue), &(p_tcb->task_queue))) {
191                        return(E_SYS_LINENO);
192                }
193        }
194        return(E_OK);
195}
196
197/*
198 *  ¥ß¥å¡Œ¥Æ¥Ã¥¯¥¹Ëè€Îž¡ºº
199 */
200static ER
201bit_mutex_mutex(ID mtxid)
202{
203        MTXCB           *p_mtxcb;
204        TCB                     *p_tcb;
205        QUEUE           *p_queue, *p_next;
206        uint_t          pri;
207
208        if (!(TMIN_MTXID <= (mtxid) && (mtxid) <= tmax_mtxid)) {
209                return(E_ID);
210        }
211        p_mtxcb = get_mtxcb(mtxid);
212
213        /*
214         *  œéŽü²œ¥Ö¥í¥Ã¥¯€Ø€Î¥Ý¥€¥ó¥¿€Îž¡ºº
215         */
216        if (p_mtxcb->p_mtxinib != &(mtxinib_table[INDEX_MTX(mtxid)])) {
217                return(E_SYS_LINENO);
218        }
219
220        /*
221         *  ¥ß¥å¡Œ¥Æ¥Ã¥¯¥¹ÂÔ€Á¥­¥å¡Œ€Îž¡ºº
222         */
223        p_queue = p_mtxcb->wait_queue.p_next;
224        if (p_queue->p_prev != &(p_mtxcb->wait_queue)) {
225                return(E_SYS_LINENO);
226        }
227        pri = TMIN_TPRI;
228        while (p_queue != &(p_mtxcb->wait_queue)) {
229                p_tcb = (TCB *) p_queue;
230                if (!VALID_TCB(p_tcb)) {
231                        return(E_SYS_LINENO);
232                }
233
234                /*
235                 *  ¥­¥å¡Œ€¬¥¿¥¹¥¯Í¥ÀèÅÙœç€Ë€Ê€Ã€Æ€€€ë€«€Îž¡ºº
236                 */
237                if (MTXPROTO(p_mtxcb) != TA_NULL) {
238                        if (p_tcb->priority < pri) {
239                                return(E_SYS_LINENO);
240                        }
241                }
242                pri = p_tcb->priority;
243
244                /*
245                 *  ¥¿¥¹¥¯ŸõÂրΞ¡ºº
246                 *
247                 *  ¥ß¥å¡Œ¥Æ¥Ã¥¯¥¹ÂÔ€ÁŸõÂրΥ¿¥¹¥¯€Îž¡ºº€Ï¡€¥¿¥¹¥¯Ëè€Îž¡ºº€Ç¹Ô€Ã
248                 *  €Æ€€€ë€¿€á¡€€³€³€Ç€Ï¹Ô€ï€Ê€€¡¥
249                 */
250                if (!TSTAT_WAIT_MTX(p_tcb->tstat)) {
251                        return(E_SYS_LINENO);
252                }
253
254                /*
255                 *  Í¥ÀèÅÙŸåžÂ€Îž¡ºº
256                 */
257                if (MTXPROTO(p_mtxcb) == TA_CEILING) {
258                        if (p_tcb->bpriority < p_mtxcb->p_mtxinib->ceilpri) {
259                                return(E_SYS_LINENO);
260                        }
261                }
262
263                /*
264                 *  ¥­¥å¡Œ€ÎŒ¡€ÎÍ×Áǀ˿ʀà
265                 */
266                p_next = p_queue->p_next;
267                if (p_next->p_prev != p_queue) {
268                        return(E_SYS_LINENO);
269                }
270                p_queue = p_next;
271        }
272
273        /*
274         *  ¥ß¥å¡Œ¥Æ¥Ã¥¯¥¹€ò¥í¥Ã¥¯€·€Æ€€€ë¥¿¥¹¥¯€Îž¡ºº
275         */
276        p_tcb = p_mtxcb->p_loctsk;
277        if (p_tcb == NULL) {
278                /*
279                 *  ¥ß¥å¡Œ¥Æ¥Ã¥¯¥¹€¬¥í¥Ã¥¯€µ€ì€Æ€€€Ê€€»þ
280                 */
281                if (!queue_empty(&(p_mtxcb->wait_queue))) {
282                        return(E_SYS_LINENO);
283                }
284        }
285        else {
286                /*
287                 *  ¥ß¥å¡Œ¥Æ¥Ã¥¯¥¹€¬¥í¥Ã¥¯€µ€ì€Æ€€€ë»þ
288                 *
289                 *  ¥ß¥å¡Œ¥Æ¥Ã¥¯¥¹€ò¥í¥Ã¥¯€·€Æ€€€ë¥¿¥¹¥¯€Îž¡ºº€Ï¡€¥¿¥¹¥¯Ëè€Îž¡
290                 *  ºº€Ç¹Ô€Ã€Æ€€€ë€¿€á¡€€³€³€Ç€Ï¹Ô€ï€Ê€€¡¥
291                 */
292                if (!VALID_TCB(p_tcb)) {
293                        return(E_SYS_LINENO);
294                }
295                if (!in_queue(&(p_tcb->mutex_queue), &(p_mtxcb->mutex_queue))) {
296                        return(E_SYS_LINENO);
297                }
298
299                /*
300                 *  Í¥ÀèÅÙŸåžÂ€Îž¡ºº
301                 */
302                if (MTXPROTO(p_mtxcb) == TA_CEILING) {
303                        if (p_tcb->bpriority < p_mtxcb->p_mtxinib->ceilpri) {
304                                return(E_SYS_LINENO);
305                        }
306                }
307        }
308        return(E_OK);
309}
310
311/*
312 *  À°¹çÀ­ž¡ºº¥ë¡Œ¥Á¥óËÜÂÎ
313 */
314ER
315bit_mutex(void)
316{
317        ID              tskid, mtxid;
318        ER              ercd;
319
320        /*
321         *  ¥¿¥¹¥¯Ëè€Îž¡ºº
322         */
323        for (tskid = TMIN_TSKID; tskid <= tmax_tskid; tskid++) {
324                ercd = bit_mutex_task(tskid);
325                if (ercd != E_OK) {
326                        return(ercd);
327                }
328        }
329
330        /*
331         *  ¥ß¥å¡Œ¥Æ¥Ã¥¯¥¹Ëè€Îž¡ºº
332         */
333        for (mtxid = TMIN_MTXID; mtxid <= tmax_mtxid; mtxid++) {
334                ercd = bit_mutex_mutex(mtxid);
335                if (ercd != E_OK) {
336                        return(ercd);
337                }
338        }
339        return(E_OK);
340}
詳しい使い方は TracBrowser を参照してください。