OSDN Git Service

Sメーター周りを修正
[trx-305dsp/dsp.git] / hirado / kernel / kernel / task_sync.c
1 /*
2  *  TOPPERS/JSP Kernel
3  *      Toyohashi Open Platform for Embedded Real-Time Systems/
4  *      Just Standard Profile Kernel
5  * 
6  *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7  *                              Toyohashi Univ. of Technology, JAPAN
8  * 
9  *  上記著作権者は,以下の (1)〜(4) の条件か,Free Software Foundation 
10  *  によって公表されている GNU General Public License の Version 2 に記
11  *  述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
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  *  本ソフトウェアは,無保証で提供されているものである.上記著作権者お
32  *  よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
33  *  含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
34  *  接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
35  * 
36  *  @(#) $Id: task_sync.c,v 1.1 2009/01/31 05:27:37 suikan Exp $
37  */
38
39 /*
40  *  タスク付属同期機能
41  */
42
43 #include "jsp_kernel.h"
44 #include "check.h"
45 #include "task.h"
46 #include "wait.h"
47
48 /*
49  *  起床待ち
50  */
51 #ifdef __slp_tsk
52
53 SYSCALL ER
54 slp_tsk()
55 {
56     WINFO   winfo;
57     ER  ercd;
58
59     LOG_SLP_TSK_ENTER();
60     CHECK_DISPATCH();
61
62     t_lock_cpu();
63     if (runtsk->wupcnt) {
64         runtsk->wupcnt = FALSE;
65         ercd = E_OK;
66     }
67     else {
68         runtsk->tstat = (TS_WAITING | TS_WAIT_SLEEP);
69         make_wait(&winfo);
70         LOG_TSKSTAT(runtsk);
71         dispatch();
72         ercd = winfo.wercd;
73     }
74     t_unlock_cpu();
75
76     exit:
77     LOG_SLP_TSK_LEAVE(ercd);
78     return(ercd);
79 }
80
81 #endif /* __slp_tsk */
82
83 /*
84  *  起床待ち(タイムアウトあり)
85  */
86 #ifdef __tslp_tsk
87
88 SYSCALL ER
89 tslp_tsk(TMO tmout)
90 {
91     WINFO   winfo;
92     TMEVTB  tmevtb;
93     ER  ercd;
94
95     LOG_TSLP_TSK_ENTER(tmout);
96     CHECK_DISPATCH();
97     CHECK_TMOUT(tmout);
98
99     t_lock_cpu();
100     if (runtsk->wupcnt) {
101         runtsk->wupcnt = FALSE;
102         ercd = E_OK;
103     }
104     else if (tmout == TMO_POL) {
105         ercd = E_TMOUT;
106     }
107     else {
108         runtsk->tstat = (TS_WAITING | TS_WAIT_SLEEP);
109         make_wait_tmout(&winfo, &tmevtb, tmout);
110         LOG_TSKSTAT(runtsk);
111         dispatch();
112         ercd = winfo.wercd;
113     }
114     t_unlock_cpu();
115
116     exit:
117     LOG_TSLP_TSK_LEAVE(ercd);
118     return(ercd);
119 }
120
121 #endif /* __tslp_tsk */
122
123 /*
124  *  タスクの起床
125  */
126 #ifdef __wup_tsk
127
128 SYSCALL ER
129 wup_tsk(ID tskid)
130 {
131     TCB *tcb;
132     UINT    tstat;
133     ER  ercd;
134
135     LOG_WUP_TSK_ENTER(tskid);
136     CHECK_TSKCTX_UNL();
137     CHECK_TSKID_SELF(tskid);
138     tcb = get_tcb_self(tskid);
139
140     t_lock_cpu();
141     if (TSTAT_DORMANT(tstat = tcb->tstat)) {
142         ercd = E_OBJ;
143     }
144     else if ((tstat & TS_WAIT_SLEEP) != 0) {
145         if (wait_complete(tcb)) {
146             dispatch();
147         }
148         ercd = E_OK;
149     }
150     else if (!(tcb->wupcnt)) {
151         tcb->wupcnt = TRUE;
152         ercd = E_OK;
153     }
154     else {
155         ercd = E_QOVR;
156     }
157     t_unlock_cpu();
158
159     exit:
160     LOG_WUP_TSK_LEAVE(ercd);
161     return(ercd);
162 }
163
164 #endif /* __wup_tsk */
165
166 /*
167  *  タスクの起床(非タスクコンテキスト用)
168  */
169 #ifdef __iwup_tsk
170
171 SYSCALL ER
172 iwup_tsk(ID tskid)
173 {
174     TCB *tcb;
175     UINT    tstat;
176     ER  ercd;
177
178     LOG_IWUP_TSK_ENTER(tskid);
179     CHECK_INTCTX_UNL();
180     CHECK_TSKID(tskid);
181     tcb = get_tcb(tskid);
182
183     i_lock_cpu();
184     if (TSTAT_DORMANT(tstat = tcb->tstat)) {
185         ercd = E_OBJ;
186     }
187     else if ((tstat & TS_WAIT_SLEEP) != 0) {
188         if (wait_complete(tcb)) {
189             reqflg = TRUE;
190         }
191         ercd = E_OK;
192     }
193     else if (!(tcb->wupcnt)) {
194         tcb->wupcnt = TRUE;
195         ercd = E_OK;
196     }
197     else {
198         ercd = E_QOVR;
199     }
200     i_unlock_cpu();
201
202     exit:
203     LOG_IWUP_TSK_LEAVE(ercd);
204     return(ercd);
205 }
206
207 #endif /* __iwup_tsk */
208
209 /*
210  *  タスク起床要求のキャンセル
211  */
212 #ifdef __can_wup
213
214 SYSCALL ER_UINT
215 can_wup(ID tskid)
216 {
217     TCB *tcb;
218     ER_UINT ercd;
219
220     LOG_CAN_WUP_ENTER(tskid);
221     CHECK_TSKCTX_UNL();
222     CHECK_TSKID_SELF(tskid);
223     tcb = get_tcb_self(tskid);
224
225     t_lock_cpu();
226     if (TSTAT_DORMANT(tcb->tstat)) {
227         ercd = E_OBJ;
228     }
229     else {
230         ercd = tcb->wupcnt ? 1 : 0;
231         tcb->wupcnt = FALSE;
232     }
233     t_unlock_cpu();
234
235     exit:
236     LOG_CAN_WUP_LEAVE(ercd);
237     return(ercd);
238 }
239
240 #endif /* __can_wup */
241
242 /*
243  *  待ち状態の強制解除
244  */
245 #ifdef __rel_wai
246
247 SYSCALL ER
248 rel_wai(ID tskid)
249 {
250     TCB *tcb;
251     ER  ercd;
252
253     LOG_REL_WAI_ENTER(tskid);
254     CHECK_TSKCTX_UNL();
255     CHECK_TSKID(tskid);
256     tcb = get_tcb(tskid);
257
258     t_lock_cpu();
259     if (!(TSTAT_WAITING(tcb->tstat))) {
260         ercd = E_OBJ;
261     }
262     else {
263         if (wait_release(tcb)) {
264             dispatch();
265         }
266         ercd = E_OK;
267     }
268     t_unlock_cpu();
269
270     exit:
271     LOG_REL_WAI_LEAVE(ercd);
272     return(ercd);
273 }
274
275 #endif /* __rel_wai */
276
277 /*
278  *  待ち状態の強制解除(非タスクコンテキスト用)
279  */
280 #ifdef __irel_wai
281
282 SYSCALL ER
283 irel_wai(ID tskid)
284 {
285     TCB *tcb;
286     ER  ercd;
287
288     LOG_IREL_WAI_ENTER(tskid);
289     CHECK_INTCTX_UNL();
290     CHECK_TSKID(tskid);
291     tcb = get_tcb(tskid);
292
293     i_lock_cpu();
294     if (!(TSTAT_WAITING(tcb->tstat))) {
295         ercd = E_OBJ;
296     }
297     else {
298         if (wait_release(tcb)) {
299             reqflg = TRUE;
300         }
301         ercd = E_OK;
302     }
303     i_unlock_cpu();
304
305     exit:
306     LOG_IREL_WAI_LEAVE(ercd);
307     return(ercd);
308 }
309
310 #endif /* __irel_wai */
311
312 /*
313  *  強制待ち状態への移行
314  */
315 #ifdef __sus_tsk
316
317 SYSCALL ER
318 sus_tsk(ID tskid)
319 {
320     TCB *tcb;
321     UINT    tstat;
322     ER  ercd;
323
324     LOG_SUS_TSK_ENTER(tskid);
325     CHECK_TSKCTX_UNL();
326     CHECK_TSKID_SELF(tskid);
327     tcb = get_tcb_self(tskid);
328
329     t_lock_cpu();
330     if (tcb == runtsk && !(enadsp)) {
331         ercd = E_CTX;
332     }
333     else if (TSTAT_DORMANT(tstat = tcb->tstat)) {
334         ercd = E_OBJ;
335     }
336     else if (TSTAT_RUNNABLE(tstat)) {
337         /*
338          *  実行できる状態から強制待ち状態への遷移
339          */
340         tcb->tstat = TS_SUSPENDED;
341         LOG_TSKSTAT(tcb);
342         if (make_non_runnable(tcb)) {
343             dispatch();
344         }
345         ercd = E_OK;
346     }
347     else if (TSTAT_SUSPENDED(tstat)) {
348         ercd = E_QOVR;
349     }
350     else {
351         /*
352          *  待ち状態から二重待ち状態への遷移
353          */
354         tcb->tstat |= TS_SUSPENDED;
355         LOG_TSKSTAT(tcb);
356         ercd = E_OK;
357     }
358     t_unlock_cpu();
359
360     exit:
361     LOG_SUS_TSK_LEAVE(ercd);
362     return(ercd);
363 }
364
365 #endif /* __sus_tsk */
366
367 /*
368  *  強制待ち状態からの再開
369  */
370 #ifdef __rsm_tsk
371
372 SYSCALL ER
373 rsm_tsk(ID tskid)
374 {
375     TCB *tcb;
376     UINT    tstat;
377     ER  ercd;
378
379     LOG_RSM_TSK_ENTER(tskid);
380     CHECK_TSKCTX_UNL();
381     CHECK_TSKID(tskid);
382     tcb = get_tcb(tskid);
383
384     t_lock_cpu();
385     if (!(TSTAT_SUSPENDED(tstat = tcb->tstat))) {
386         ercd = E_OBJ;
387     }
388     else if (!(TSTAT_WAITING(tstat))) {
389         /*
390          *  強制待ち状態から実行できる状態への遷移
391          */
392         if (make_runnable(tcb)) {
393             dispatch();
394         }
395         ercd = E_OK;
396     }
397     else {
398         /*
399          *  二重待ち状態から待ち状態への遷移
400          */
401         tcb->tstat &= ~TS_SUSPENDED;
402         LOG_TSKSTAT(tcb);
403         ercd = E_OK;
404     }
405     t_unlock_cpu();
406
407     exit:
408     LOG_RSM_TSK_LEAVE(ercd);
409     return(ercd);
410 }
411
412 #endif /* __rsm_tsk */
413
414 /*
415  *  強制待ち状態からの強制再開
416  *
417  *  JSPカーネルでは,frsm_tsk と rsm_tsk は同一の処理となる.frsm_tsk 
418  *  が呼ばれると,frsm_tsk と rsm_tsk の両方のサービスコールのトレース
419  *  ログが出力される.ログ取得後に rsm_tsk のトレースログを削除するこ
420  *  とが必要である.rsm_tsk のトレースログを正しく削除するためには,タ
421  *  スクディスパッチのログと,タスク例外処理のログも取得することが必要
422  *  となるので,注意が必要である.
423  */
424 #ifdef __frsm_tsk
425
426 SYSCALL ER
427 frsm_tsk(ID tskid)
428 {
429     ER  ercd;
430
431     LOG_FRSM_TSK_ENTER(tskid);
432     ercd = rsm_tsk(tskid);
433     LOG_FRSM_TSK_LEAVE(ercd);
434     return(ercd);
435 }
436
437 #endif /* __frsm_tsk */
438
439 /*
440  *  自タスクの遅延
441  */
442 #ifdef __dly_tsk
443
444 SYSCALL ER
445 dly_tsk(RELTIM dlytim)
446 {
447     WINFO   winfo;
448     TMEVTB  tmevtb;
449     ER  ercd;
450
451     LOG_DLY_TSK_ENTER(dlytim);
452     CHECK_DISPATCH();
453     CHECK_PAR(dlytim <= TMAX_RELTIM);
454
455     t_lock_cpu();
456     runtsk->tstat = TS_WAITING;
457     make_non_runnable(runtsk);
458     runtsk->winfo = &winfo;
459     winfo.tmevtb = &tmevtb;
460     tmevtb_enqueue(&tmevtb, dlytim, (CBACK) wait_tmout_ok, (VP) runtsk);
461     LOG_TSKSTAT(runtsk);
462     dispatch();
463     ercd = winfo.wercd;
464     t_unlock_cpu();
465
466     exit:
467     LOG_DLY_TSK_LEAVE(ercd);
468     return(ercd);
469 }
470
471 #endif /* __dly_tsk */