source: kernel/task_sync.c

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

TOPPERS/ASP 1.9.1

ファイルサイズ: 9.7 KB
 
1/*
2 *  TOPPERS/ASP Kernel
3 *      Toyohashi Open Platform for Embedded Real-Time Systems/
4 *      Advanced Standard Profile Kernel
5 *
6 *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7 *                              Toyohashi Univ. of Technology, JAPAN
8 *  Copyright (C) 2005-2009 by Embedded and Real-Time Systems Laboratory
9 *              Graduate School of Information Science, Nagoya Univ., JAPAN
10 *
11 *  Ÿåµ­Ãøºîž¢ŒÔ€Ï¡€°Ê²Œ€Î(1)¡Á(4)€ÎŸò·ï€òËþ€¿€¹Ÿì¹ç€ËžÂ€ê¡€ËÜ¥œ¥Õ¥È¥Š¥§
12 *  ¥¢¡ÊËÜ¥œ¥Õ¥È¥Š¥§¥¢€ò²þÊÑ€·€¿€â€Î€òŽÞ€à¡¥°Ê²ŒÆ±€ž¡Ë€ò»ÈÍÑ¡ŠÊ£Àœ¡Š²þ
13 *  ÊÑ¡ŠºÆÇÛÉۡʰʲŒ¡€ÍøÍрȞƀ֡ˀ¹€ë€³€È€ò̵œþ€ÇµöÂú€¹€ë¡¥
14 *  (1) ËÜ¥œ¥Õ¥È¥Š¥§¥¢€ò¥œ¡Œ¥¹¥³¡Œ¥É€Î·Á€ÇÍøÍÑ€¹€ëŸì¹ç€Ë€Ï¡€Ÿåµ­€ÎÃøºî
15 *      ž¢ÉœŒš¡€€³€ÎÍøÍÑŸò·ï€ª€è€Ó²Œµ­€Î̵ÊÝŸÚµ¬Äꀬ¡€€œ€Î€Þ€Þ€Î·Á€Ç¥œ¡Œ
16 *      ¥¹¥³¡Œ¥ÉÃæ€ËŽÞ€Þ€ì€Æ€€€ë€³€È¡¥
17 *  (2) ËÜ¥œ¥Õ¥È¥Š¥§¥¢€ò¡€¥é¥€¥Ö¥é¥ê·ÁŒ°€Ê€É¡€ÂŸ€Î¥œ¥Õ¥È¥Š¥§¥¢³«È¯€Ë»È
18 *      Íрǀ­€ë·Á€ÇºÆÇÛÉÛ€¹€ëŸì¹ç€Ë€Ï¡€ºÆÇÛÉÛ€ËÈŒ€Š¥É¥­¥å¥á¥ó¥È¡ÊÍøÍÑ
19 *      ŒÔ¥Þ¥Ë¥å¥¢¥ë€Ê€É¡Ë€Ë¡€Ÿåµ­€ÎÃøºîž¢ÉœŒš¡€€³€ÎÍøÍÑŸò·ï€ª€è€Ó²Œµ­
20 *      €Î̵ÊÝŸÚµ¬Äê€ò·ÇºÜ€¹€ë€³€È¡¥
21 *  (3) ËÜ¥œ¥Õ¥È¥Š¥§¥¢€ò¡€µ¡Žï€ËÁȀ߹þ€à€Ê€É¡€ÂŸ€Î¥œ¥Õ¥È¥Š¥§¥¢³«È¯€Ë»È
22 *      Íрǀ­€Ê€€·Á€ÇºÆÇÛÉÛ€¹€ëŸì¹ç€Ë€Ï¡€Œ¡€Î€€€º€ì€«€ÎŸò·ï€òËþ€¿€¹€³
23 *      €È¡¥
24 *    (a) ºÆÇÛÉÛ€ËÈŒ€Š¥É¥­¥å¥á¥ó¥È¡ÊÍøÍьԥޥ˥奢¥ë€Ê€É¡Ë€Ë¡€Ÿåµ­€ÎÃø
25 *        ºîž¢ÉœŒš¡€€³€ÎÍøÍÑŸò·ï€ª€è€Ó²Œµ­€Î̵ÊÝŸÚµ¬Äê€ò·ÇºÜ€¹€ë€³€È¡¥
26 *    (b) ºÆÇÛÉۀηÁÂÖ€ò¡€ÊÌ€ËÄê€á€ëÊýË¡€Ë€è€Ã€Æ¡€TOPPERS¥×¥í¥ž¥§¥¯¥È€Ë
27 *        Êó¹ð€¹€ë€³€È¡¥
28 *  (4) ËÜ¥œ¥Õ¥È¥Š¥§¥¢€ÎÍøÍрˀè€êÄŸÀÜŪ€Þ€¿€ÏŽÖÀÜŪ€ËÀž€ž€ë€€€«€Ê€ë»
29 *      ³²€«€é€â¡€Ÿåµ­Ãøºîž¢ŒÔ€ª€è€ÓTOPPERS¥×¥í¥ž¥§¥¯¥È€òÌÈÀÕ€¹€ë€³€È¡¥
30 *      €Þ€¿¡€ËÜ¥œ¥Õ¥È¥Š¥§¥¢€Î¥æ¡Œ¥¶€Þ€¿€Ï¥š¥ó¥É¥æ¡Œ¥¶€«€é€Î€€€«€Ê€ëÍý
31 *      ͳ€ËŽð€Å€¯ÀÁµá€«€é€â¡€Ÿåµ­Ãøºîž¢ŒÔ€ª€è€ÓTOPPERS¥×¥í¥ž¥§¥¯¥È€ò
32 *      ÌÈÀÕ€¹€ë€³€È¡¥
33 *
34 *  ËÜ¥œ¥Õ¥È¥Š¥§¥¢€Ï¡€ÌµÊÝŸÚ€ÇÄó¶¡€µ€ì€Æ€€€ë€â€Î€Ç€¢€ë¡¥Ÿåµ­Ãøºîž¢ŒÔ€ª
35 *  €è€ÓTOPPERS¥×¥í¥ž¥§¥¯¥È€Ï¡€ËÜ¥œ¥Õ¥È¥Š¥§¥¢€ËŽØ€·€Æ¡€ÆÃÄê€Î»ÈÍÑÌÜŪ
36 *  €ËÂЀ¹€ëŬ¹çÀ­€âŽÞ€á€Æ¡€€€€«€Ê€ëÊÝŸÚ€â¹Ô€ï€Ê€€¡¥€Þ€¿¡€ËÜ¥œ¥Õ¥È¥Š¥§
37 *  ¥¢€ÎÍøÍрˀè€êÄŸÀÜŪ€Þ€¿€ÏŽÖÀÜŪ€ËÀž€ž€¿€€€«€Ê€ë»³²€ËŽØ€·€Æ€â¡€€œ
38 *  €ÎÀÕÇ€€òÉé€ï€Ê€€¡¥
39 *
40 *  @(#) $Id$
41 */
42
43/*
44 *              ¥¿¥¹¥¯ÉÕ°ƱŽüµ¡Çœ
45 */
46
47#include "kernel_impl.h"
48#include "check.h"
49#include "task.h"
50#include "wait.h"
51
52/*
53 *  ¥È¥ì¡Œ¥¹¥í¥°¥Þ¥¯¥í€Î¥Ç¥Õ¥©¥ë¥ÈÄêµÁ
54 */
55#ifndef LOG_SLP_TSK_ENTER
56#define LOG_SLP_TSK_ENTER()
57#endif /* LOG_SLP_TSK_ENTER */
58
59#ifndef LOG_SLP_TSK_LEAVE
60#define LOG_SLP_TSK_LEAVE(ercd)
61#endif /* LOG_SLP_TSK_LEAVE */
62
63#ifndef LOG_TSLP_TSK_ENTER
64#define LOG_TSLP_TSK_ENTER(tmout)
65#endif /* LOG_TSLP_TSK_ENTER */
66
67#ifndef LOG_TSLP_TSK_LEAVE
68#define LOG_TSLP_TSK_LEAVE(ercd)
69#endif /* LOG_TSLP_TSK_LEAVE */
70
71#ifndef LOG_WUP_TSK_ENTER
72#define LOG_WUP_TSK_ENTER(tskid)
73#endif /* LOG_WUP_TSK_ENTER */
74
75#ifndef LOG_WUP_TSK_LEAVE
76#define LOG_WUP_TSK_LEAVE(ercd)
77#endif /* LOG_WUP_TSK_LEAVE */
78
79#ifndef LOG_IWUP_TSK_ENTER
80#define LOG_IWUP_TSK_ENTER(tskid)
81#endif /* LOG_IWUP_TSK_ENTER */
82
83#ifndef LOG_IWUP_TSK_LEAVE
84#define LOG_IWUP_TSK_LEAVE(ercd)
85#endif /* LOG_IWUP_TSK_LEAVE */
86
87#ifndef LOG_CAN_WUP_ENTER
88#define LOG_CAN_WUP_ENTER(tskid)
89#endif /* LOG_CAN_WUP_ENTER */
90
91#ifndef LOG_CAN_WUP_LEAVE
92#define LOG_CAN_WUP_LEAVE(ercd)
93#endif /* LOG_CAN_WUP_LEAVE */
94
95#ifndef LOG_REL_WAI_ENTER
96#define LOG_REL_WAI_ENTER(tskid)
97#endif /* LOG_REL_WAI_ENTER */
98
99#ifndef LOG_REL_WAI_LEAVE
100#define LOG_REL_WAI_LEAVE(ercd)
101#endif /* LOG_REL_WAI_LEAVE */
102
103#ifndef LOG_IREL_WAI_ENTER
104#define LOG_IREL_WAI_ENTER(tskid)
105#endif /* LOG_IREL_WAI_ENTER */
106
107#ifndef LOG_IREL_WAI_LEAVE
108#define LOG_IREL_WAI_LEAVE(ercd)
109#endif /* LOG_IREL_WAI_LEAVE */
110
111#ifndef LOG_SUS_TSK_ENTER
112#define LOG_SUS_TSK_ENTER(tskid)
113#endif /* LOG_SUS_TSK_ENTER */
114
115#ifndef LOG_SUS_TSK_LEAVE
116#define LOG_SUS_TSK_LEAVE(ercd)
117#endif /* LOG_SUS_TSK_LEAVE */
118
119#ifndef LOG_RSM_TSK_ENTER
120#define LOG_RSM_TSK_ENTER(tskid)
121#endif /* LOG_RSM_TSK_ENTER */
122
123#ifndef LOG_RSM_TSK_LEAVE
124#define LOG_RSM_TSK_LEAVE(ercd)
125#endif /* LOG_RSM_TSK_LEAVE */
126
127#ifndef LOG_DLY_TSK_ENTER
128#define LOG_DLY_TSK_ENTER(dlytim)
129#endif /* LOG_DLY_TSK_ENTER */
130
131#ifndef LOG_DLY_TSK_LEAVE
132#define LOG_DLY_TSK_LEAVE(ercd)
133#endif /* LOG_DLY_TSK_LEAVE */
134
135/*
136 *  µ¯Ÿ²ÂÔ€Á
137 */
138#ifdef TOPPERS_slp_tsk
139
140ER
141slp_tsk(void)
142{
143        WINFO   winfo;
144        ER              ercd;
145
146        LOG_SLP_TSK_ENTER();
147        CHECK_DISPATCH();
148
149        t_lock_cpu();
150        if (p_runtsk->wupque) {
151                p_runtsk->wupque = false;
152                ercd = E_OK;
153        }
154        else {
155                p_runtsk->tstat = (TS_WAITING | TS_WAIT_SLP);
156                make_wait(&winfo);
157                LOG_TSKSTAT(p_runtsk);
158                dispatch();
159                ercd = winfo.wercd;
160        }
161        t_unlock_cpu();
162
163  error_exit:
164        LOG_SLP_TSK_LEAVE(ercd);
165        return(ercd);
166}
167
168#endif /* TOPPERS_slp_tsk */
169
170/*
171 *  µ¯Ÿ²ÂÔ€Á¡Ê¥¿¥€¥à¥¢¥Š¥È€¢€ê¡Ë
172 */
173#ifdef TOPPERS_tslp_tsk
174
175ER
176tslp_tsk(TMO tmout)
177{
178        WINFO   winfo;
179        TMEVTB  tmevtb;
180        ER              ercd;
181
182        LOG_TSLP_TSK_ENTER(tmout);
183        CHECK_DISPATCH();
184        CHECK_TMOUT(tmout);
185
186        t_lock_cpu();
187        if (p_runtsk->wupque) {
188                p_runtsk->wupque = false;
189                ercd = E_OK;
190        }
191        else if (tmout == TMO_POL) {
192                ercd = E_TMOUT;
193        }
194        else {
195                p_runtsk->tstat = (TS_WAITING | TS_WAIT_SLP);
196                make_wait_tmout(&winfo, &tmevtb, tmout);
197                LOG_TSKSTAT(p_runtsk);
198                dispatch();
199                ercd = winfo.wercd;
200        }
201        t_unlock_cpu();
202
203  error_exit:
204        LOG_TSLP_TSK_LEAVE(ercd);
205        return(ercd);
206}
207
208#endif /* TOPPERS_tslp_tsk */
209
210/*
211 *  ¥¿¥¹¥¯€Îµ¯Ÿ²
212 */
213#ifdef TOPPERS_wup_tsk
214
215ER
216wup_tsk(ID tskid)
217{
218        TCB             *p_tcb;
219        ER              ercd;
220
221        LOG_WUP_TSK_ENTER(tskid);
222        CHECK_TSKCTX_UNL();
223        CHECK_TSKID_SELF(tskid);
224        p_tcb = get_tcb_self(tskid);
225
226        t_lock_cpu();
227        if (TSTAT_DORMANT(p_tcb->tstat)) {
228                ercd = E_OBJ;
229        }
230        else if (TSTAT_WAIT_SLP(p_tcb->tstat)) {
231                if (wait_complete(p_tcb)) {
232                        dispatch();
233                }
234                ercd = E_OK;
235        }
236        else if (!(p_tcb->wupque)) {
237                p_tcb->wupque = true;
238                ercd = E_OK;
239        }
240        else {
241                ercd = E_QOVR;
242        }
243        t_unlock_cpu();
244
245  error_exit:
246        LOG_WUP_TSK_LEAVE(ercd);
247        return(ercd);
248}
249
250#endif /* TOPPERS_wup_tsk */
251
252/*
253 *  ¥¿¥¹¥¯€Îµ¯Ÿ²¡ÊÈ󥿥¹¥¯¥³¥ó¥Æ¥­¥¹¥ÈÍÑ¡Ë
254 */
255#ifdef TOPPERS_iwup_tsk
256
257ER
258iwup_tsk(ID tskid)
259{
260        TCB             *p_tcb;
261        ER              ercd;
262
263        LOG_IWUP_TSK_ENTER(tskid);
264        CHECK_INTCTX_UNL();
265        CHECK_TSKID(tskid);
266        p_tcb = get_tcb(tskid);
267
268        i_lock_cpu();
269        if (TSTAT_DORMANT(p_tcb->tstat)) {
270                ercd = E_OBJ;
271        }
272        else if (TSTAT_WAIT_SLP(p_tcb->tstat)) {
273                if (wait_complete(p_tcb)) {
274                        reqflg = true;
275                }
276                ercd = E_OK;
277        }
278        else if (!(p_tcb->wupque)) {
279                p_tcb->wupque = true;
280                ercd = E_OK;
281        }
282        else {
283                ercd = E_QOVR;
284        }
285        i_unlock_cpu();
286
287  error_exit:
288        LOG_IWUP_TSK_LEAVE(ercd);
289        return(ercd);
290}
291
292#endif /* TOPPERS_iwup_tsk */
293
294/*
295 *  ¥¿¥¹¥¯µ¯Ÿ²Í×µá€Î¥­¥ã¥ó¥»¥ë
296 */
297#ifdef TOPPERS_can_wup
298
299ER_UINT
300can_wup(ID tskid)
301{
302        TCB             *p_tcb;
303        ER_UINT ercd;
304
305        LOG_CAN_WUP_ENTER(tskid);
306        CHECK_TSKCTX_UNL();
307        CHECK_TSKID_SELF(tskid);
308        p_tcb = get_tcb_self(tskid);
309
310        t_lock_cpu();
311        if (TSTAT_DORMANT(p_tcb->tstat)) {
312                ercd = E_OBJ;
313        }
314        else {
315                ercd = p_tcb->wupque ? 1 : 0;
316                p_tcb->wupque = false;
317        }
318        t_unlock_cpu();
319
320  error_exit:
321        LOG_CAN_WUP_LEAVE(ercd);
322        return(ercd);
323}
324
325#endif /* TOPPERS_can_wup */
326
327/*
328 *  ÂÔ€ÁŸõÂրζ¯À©²òœü
329 */
330#ifdef TOPPERS_rel_wai
331
332ER
333rel_wai(ID tskid)
334{
335        TCB             *p_tcb;
336        ER              ercd;
337
338        LOG_REL_WAI_ENTER(tskid);
339        CHECK_TSKCTX_UNL();
340        CHECK_TSKID(tskid);
341        p_tcb = get_tcb(tskid);
342
343        t_lock_cpu();
344        if (!TSTAT_WAITING(p_tcb->tstat)) {
345                ercd = E_OBJ;
346        }
347        else {
348                if (wait_release(p_tcb)) {
349                        dispatch();
350                }
351                ercd = E_OK;
352        }
353        t_unlock_cpu();
354
355  error_exit:
356        LOG_REL_WAI_LEAVE(ercd);
357        return(ercd);
358}
359
360#endif /* TOPPERS_rel_wai */
361
362/*
363 *  ÂÔ€ÁŸõÂրζ¯À©²òœü¡ÊÈ󥿥¹¥¯¥³¥ó¥Æ¥­¥¹¥ÈÍÑ¡Ë
364 */
365#ifdef TOPPERS_irel_wai
366
367ER
368irel_wai(ID tskid)
369{
370        TCB             *p_tcb;
371        ER              ercd;
372
373        LOG_IREL_WAI_ENTER(tskid);
374        CHECK_INTCTX_UNL();
375        CHECK_TSKID(tskid);
376        p_tcb = get_tcb(tskid);
377
378        i_lock_cpu();
379        if (!TSTAT_WAITING(p_tcb->tstat)) {
380                ercd = E_OBJ;
381        }
382        else {
383                if (wait_release(p_tcb)) {
384                        reqflg = true;
385                }
386                ercd = E_OK;
387        }
388        i_unlock_cpu();
389
390  error_exit:
391        LOG_IREL_WAI_LEAVE(ercd);
392        return(ercd);
393}
394
395#endif /* TOPPERS_irel_wai */
396
397/*
398 *  ¶¯À©ÂÔ€ÁŸõÂր؀ΰܹÔ
399 */
400#ifdef TOPPERS_sus_tsk
401
402ER
403sus_tsk(ID tskid)
404{
405        TCB             *p_tcb;
406        ER              ercd;
407
408        LOG_SUS_TSK_ENTER(tskid);
409        CHECK_TSKCTX_UNL();
410        CHECK_TSKID_SELF(tskid);
411        p_tcb = get_tcb_self(tskid);
412
413        t_lock_cpu();
414        if (p_tcb == p_runtsk && !dspflg) {
415                ercd = E_CTX;
416        }
417        else if (TSTAT_DORMANT(p_tcb->tstat)) {
418                ercd = E_OBJ;
419        }
420        else if (TSTAT_RUNNABLE(p_tcb->tstat)) {
421                /*
422                 *  ŒÂ¹Ô€Ç€­€ëŸõÂÖ€«€é¶¯À©ÂÔ€ÁŸõÂր؀ÎÁ«°Ü
423                 */
424                p_tcb->tstat = TS_SUSPENDED;
425                LOG_TSKSTAT(p_tcb);
426                if (make_non_runnable(p_tcb)) {
427                        dispatch();
428                }
429                ercd = E_OK;
430        }
431        else if (TSTAT_SUSPENDED(p_tcb->tstat)) {
432                ercd = E_QOVR;
433        }
434        else {
435                /*
436                 *  ÂÔ€ÁŸõÂÖ€«€éÆóœÅÂÔ€ÁŸõÂր؀ÎÁ«°Ü
437                 */
438                p_tcb->tstat |= TS_SUSPENDED;
439                LOG_TSKSTAT(p_tcb);
440                ercd = E_OK;
441        }
442        t_unlock_cpu();
443
444  error_exit:
445        LOG_SUS_TSK_LEAVE(ercd);
446        return(ercd);
447}
448
449#endif /* TOPPERS_sus_tsk */
450
451/*
452 *  ¶¯À©ÂÔ€ÁŸõÂÖ€«€é€ÎºÆ³«
453 */
454#ifdef TOPPERS_rsm_tsk
455
456ER
457rsm_tsk(ID tskid)
458{
459        TCB             *p_tcb;
460        ER              ercd;
461
462        LOG_RSM_TSK_ENTER(tskid);
463        CHECK_TSKCTX_UNL();
464        CHECK_TSKID(tskid);
465        p_tcb = get_tcb(tskid);
466
467        t_lock_cpu();
468        if (!TSTAT_SUSPENDED(p_tcb->tstat)) {
469                ercd = E_OBJ;
470        }
471        else if (!TSTAT_WAITING(p_tcb->tstat)) {
472                /*
473                 *  ¶¯À©ÂÔ€ÁŸõÂÖ€«€éŒÂ¹Ô€Ç€­€ëŸõÂր؀ÎÁ«°Ü
474                 */
475                p_tcb->tstat = TS_RUNNABLE;
476                LOG_TSKSTAT(p_tcb);
477                if (make_runnable(p_tcb)) {
478                        dispatch();
479                }
480                ercd = E_OK;
481        }
482        else {
483                /*
484                 *  ÆóœÅÂÔ€ÁŸõÂÖ€«€éÂÔ€ÁŸõÂր؀ÎÁ«°Ü
485                 */
486                p_tcb->tstat &= ~TS_SUSPENDED;
487                LOG_TSKSTAT(p_tcb);
488                ercd = E_OK;
489        }
490        t_unlock_cpu();
491
492  error_exit:
493        LOG_RSM_TSK_LEAVE(ercd);
494        return(ercd);
495}
496
497#endif /* TOPPERS_rsm_tsk */
498
499/*
500 *  Œ«¥¿¥¹¥¯€ÎÃÙ±ä
501 */
502#ifdef TOPPERS_dly_tsk
503
504ER
505dly_tsk(RELTIM dlytim)
506{
507        WINFO   winfo;
508        TMEVTB  tmevtb;
509        ER              ercd;
510
511        LOG_DLY_TSK_ENTER(dlytim);
512        CHECK_DISPATCH();
513        CHECK_PAR(dlytim <= TMAX_RELTIM);
514
515        t_lock_cpu();
516        p_runtsk->tstat = (TS_WAITING | TS_WAIT_DLY);
517        (void) make_non_runnable(p_runtsk);
518        p_runtsk->p_winfo = &winfo;
519        winfo.p_tmevtb = &tmevtb;
520        tmevtb_enqueue(&tmevtb, dlytim, (CBACK) wait_tmout_ok, (void *) p_runtsk);
521        LOG_TSKSTAT(p_runtsk);
522        dispatch();
523        ercd = winfo.wercd;
524        t_unlock_cpu();
525
526  error_exit:
527        LOG_DLY_TSK_LEAVE(ercd);
528        return(ercd);
529}
530
531#endif /* TOPPERS_dly_tsk */
詳しい使い方は TracBrowser を参照してください。