OSDN Git Service

58c6dba01cc14b2cd8a66f5c13e296dd0ec70553
[trx-305dsp/dsp.git] / hirado / kernel / kernel / task_manage.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_manage.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 __act_tsk
52
53 SYSCALL ER
54 act_tsk(ID tskid)
55 {
56     TCB *tcb;
57     ER  ercd;
58
59     LOG_ACT_TSK_ENTER(tskid);
60     CHECK_TSKCTX_UNL();
61     CHECK_TSKID_SELF(tskid);
62     tcb = get_tcb_self(tskid);
63
64     t_lock_cpu();
65     if (TSTAT_DORMANT(tcb->tstat)) {
66         if (make_active(tcb)) {
67             dispatch();
68         }
69         ercd = E_OK;
70     }
71     else if (!(tcb->actcnt)) {
72         tcb->actcnt = TRUE;
73         ercd = E_OK;
74     }
75     else {
76         ercd = E_QOVR;
77     }
78     t_unlock_cpu();
79
80     exit:
81     LOG_ACT_TSK_LEAVE(ercd);
82     return(ercd);
83 }
84
85 #endif /* __act_tsk */
86
87 /*
88  *  タスクの起動(非タスクコンテキスト用)
89  */
90 #ifdef __iact_tsk
91
92 SYSCALL ER
93 iact_tsk(ID tskid)
94 {
95     TCB *tcb;
96     ER  ercd;
97
98     LOG_IACT_TSK_ENTER(tskid);
99     CHECK_INTCTX_UNL();
100     CHECK_TSKID(tskid);
101     tcb = get_tcb(tskid);
102
103     i_lock_cpu();
104     if (TSTAT_DORMANT(tcb->tstat)) {
105         if (make_active(tcb)) {
106             reqflg = TRUE;
107         }
108         ercd = E_OK;
109     }
110     else if (!(tcb->actcnt)) {
111         tcb->actcnt = TRUE;
112         ercd = E_OK;
113     }
114     else {
115         ercd = E_QOVR;
116     }
117     i_unlock_cpu();
118
119     exit:
120     LOG_IACT_TSK_LEAVE(ercd);
121     return(ercd);
122 }
123
124 #endif /* __iact_tsk */
125
126 /*
127  *  タスク起動要求のキャンセル
128  */
129 #ifdef __can_act
130
131 SYSCALL ER_UINT
132 can_act(ID tskid)
133 {
134     TCB *tcb;
135     ER_UINT ercd;
136
137     LOG_CAN_ACT_ENTER(tskid);
138     CHECK_TSKCTX_UNL();
139     CHECK_TSKID_SELF(tskid);
140     tcb = get_tcb_self(tskid);
141
142     t_lock_cpu();
143     ercd = tcb->actcnt ? 1 : 0;
144     tcb->actcnt = FALSE;
145     t_unlock_cpu();
146
147     exit:
148     LOG_CAN_ACT_LEAVE(ercd);
149     return(ercd);
150 }
151
152 #endif /* __can_act */
153
154 /*
155  *  自タスクの終了
156  */
157 #ifdef __ext_tsk
158
159 SYSCALL void
160 ext_tsk(void)
161 {
162     LOG_EXT_TSK_ENTER();
163
164 #ifdef ACTIVATED_STACK_SIZE
165     /*
166      *  create_context と activate_context で,使用中のスタック領
167      *  域を破壊しないように,スタック上にダミー領域を確保する.
168      */
169     (void) alloca(ACTIVATED_STACK_SIZE);
170 #endif /* ACTIVATED_STACK_SIZE */
171
172     if (sense_context()) {
173         /*
174          *  非タスクコンテキストから ext_tsk が呼ばれた場合,
175          *  システムログにエラーを記録し,そのまま実行を続ける
176          *  が, 動作は保証されない.
177          */
178         syslog_0(LOG_EMERG,
179             "ext_tsk is called from non-task contexts.");
180     }
181     if (sense_lock()) {
182         /*
183          *  CPUロック状態で ext_tsk が呼ばれた場合は,CPUロック
184          *  を解除してからタスクを終了する.実装上は,サービス
185          *  コール内でのCPUロックを省略すればよいだけ.
186          */
187         syslog_0(LOG_WARNING,
188             "ext_tsk is called from CPU locked state.");
189     }
190     else {
191         if (sense_context()) {
192             i_lock_cpu();
193         }
194         else  {
195             t_lock_cpu();
196         }
197     }
198     if (!(enadsp)) {
199         /*
200          *  ディスパッチ禁止状態で ext_tsk が呼ばれた場合は,
201          *  ディスパッチ許可状態にしてからタスクを終了する.
202          */
203         syslog_0(LOG_WARNING,
204             "ext_tsk is called from dispatch disabled state.");
205         enadsp = TRUE;
206     }
207     exit_task();
208 }
209
210 #endif /* __ext_tsk */
211
212 /*
213  *  タスクの強制終了
214  */
215 #ifdef __ter_tsk
216
217 SYSCALL ER
218 ter_tsk(ID tskid)
219 {
220     TCB *tcb;
221     UINT    tstat;
222     ER  ercd;
223
224     LOG_TER_TSK_ENTER(tskid);
225     CHECK_TSKCTX_UNL();
226     CHECK_TSKID(tskid);
227     tcb = get_tcb(tskid);
228     CHECK_NONSELF(tcb);
229
230     t_lock_cpu();
231     if (TSTAT_DORMANT(tstat = tcb->tstat)) {
232         ercd = E_OBJ;
233     }
234     else {
235         if (TSTAT_RUNNABLE(tstat)) {
236             make_non_runnable(tcb);
237         }
238         else if (TSTAT_WAITING(tstat)) {
239             wait_cancel(tcb);
240         }
241         make_dormant(tcb);
242         if (tcb->actcnt) {
243             tcb->actcnt = FALSE;
244             if (make_active(tcb)) {
245                 dispatch();
246             }
247         }
248         ercd = E_OK;
249     }
250     t_unlock_cpu();
251
252     exit:
253     LOG_TER_TSK_LEAVE(ercd);
254     return(ercd);
255 }
256
257 #endif /* __ter_tsk */
258
259 /*
260  *  タスク優先度の変更
261  */
262 #ifdef __chg_pri
263
264 SYSCALL ER
265 chg_pri(ID tskid, PRI tskpri)
266 {
267     TCB *tcb;
268     UINT    newpri;
269     UINT    tstat;
270     ER  ercd;
271
272     LOG_CHG_PRI_ENTER(tskid, tskpri);
273     CHECK_TSKCTX_UNL();
274     CHECK_TSKID_SELF(tskid);
275     CHECK_TPRI_INI(tskpri);
276     tcb = get_tcb_self(tskid);
277     newpri = (tskpri == TPRI_INI) ? tcb->tinib->ipriority
278                     : INT_PRIORITY(tskpri);
279
280     t_lock_cpu();
281     if (TSTAT_DORMANT(tstat = tcb->tstat)) {
282         ercd = E_OBJ;
283     }
284     else if (TSTAT_RUNNABLE(tstat)) {
285         if (change_priority(tcb, newpri)) {
286             dispatch();
287         }
288         ercd = E_OK;
289     }
290     else {
291         tcb->priority = newpri;
292         if ((tstat & TS_WAIT_WOBJCB) != 0) {
293             wobj_change_priority(((WINFO_WOBJ *)(tcb->winfo))
294                             ->wobjcb, tcb);
295         }
296         ercd = E_OK;
297     }
298     t_unlock_cpu();
299
300     exit:
301     LOG_CHG_PRI_LEAVE(ercd);
302     return(ercd);
303 }
304
305 #endif /* __chg_pri */
306
307 /*
308  *  タスク優先度の参照
309  */
310 #ifdef __get_pri
311
312 SYSCALL ER
313 get_pri(ID tskid, PRI *p_tskpri)
314 {
315     TCB *tcb;
316     ER  ercd;
317
318     LOG_GET_PRI_ENTER(tskid, p_tskpri);
319     CHECK_TSKCTX_UNL();
320     CHECK_TSKID_SELF(tskid);
321     tcb = get_tcb_self(tskid);
322
323     t_lock_cpu();
324     if (TSTAT_DORMANT(tcb->tstat)) {
325         ercd = E_OBJ;
326     }
327     else {
328         *p_tskpri = EXT_TSKPRI(tcb->priority);
329         ercd = E_OK;
330     }
331     t_unlock_cpu();
332
333     exit:
334     LOG_GET_PRI_LEAVE(ercd, *p_tskpri);
335     return(ercd);
336 }
337
338 #endif /* __get_pri */