source: asp_wo_cfg/trunk/kernel/task_manage.c@ 70

Last change on this file since 70 was 70, checked in by ertl-hiro, 10 years ago

ASPカーネルの動的生成パッケージに追従。

  • Property svn:keywords set to Id
File size: 10.3 KB
Line 
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-2014 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: task_manage.c 70 2014-04-16 23:04:43Z ertl-hiro $
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_CRE_TSK_ENTER
56#define LOG_CRE_TSK_ENTER(tskid, pk_ctsk)
57#endif /* LOG_CRE_TSK_ENTER */
58
59#ifndef LOG_CRE_TSK_LEAVE
60#define LOG_CRE_TSK_LEAVE(ercd)
61#endif /* LOG_CRE_TSK_LEAVE */
62
63#ifndef LOG_ACT_TSK_ENTER
64#define LOG_ACT_TSK_ENTER(tskid)
65#endif /* LOG_ACT_TSK_ENTER */
66
67#ifndef LOG_ACT_TSK_LEAVE
68#define LOG_ACT_TSK_LEAVE(ercd)
69#endif /* LOG_ACT_TSK_LEAVE */
70
71#ifndef LOG_IACT_TSK_ENTER
72#define LOG_IACT_TSK_ENTER(tskid)
73#endif /* LOG_IACT_TSK_ENTER */
74
75#ifndef LOG_IACT_TSK_LEAVE
76#define LOG_IACT_TSK_LEAVE(ercd)
77#endif /* LOG_IACT_TSK_LEAVE */
78
79#ifndef LOG_CAN_ACT_ENTER
80#define LOG_CAN_ACT_ENTER(tskid)
81#endif /* LOG_CAN_ACT_ENTER */
82
83#ifndef LOG_CAN_ACT_LEAVE
84#define LOG_CAN_ACT_LEAVE(ercd)
85#endif /* LOG_CAN_ACT_LEAVE */
86
87#ifndef LOG_EXT_TSK_ENTER
88#define LOG_EXT_TSK_ENTER()
89#endif /* LOG_EXT_TSK_ENTER */
90
91#ifndef LOG_EXT_TSK_LEAVE
92#define LOG_EXT_TSK_LEAVE(ercd)
93#endif /* LOG_EXT_TSK_LEAVE */
94
95#ifndef LOG_TER_TSK_ENTER
96#define LOG_TER_TSK_ENTER(tskid)
97#endif /* LOG_TER_TSK_ENTER */
98
99#ifndef LOG_TER_TSK_LEAVE
100#define LOG_TER_TSK_LEAVE(ercd)
101#endif /* LOG_TER_TSK_LEAVE */
102
103#ifndef LOG_CHG_PRI_ENTER
104#define LOG_CHG_PRI_ENTER(tskid, tskpri)
105#endif /* LOG_CHG_PRI_ENTER */
106
107#ifndef LOG_CHG_PRI_LEAVE
108#define LOG_CHG_PRI_LEAVE(ercd)
109#endif /* LOG_CHG_PRI_LEAVE */
110
111#ifndef LOG_GET_PRI_ENTER
112#define LOG_GET_PRI_ENTER(tskid, p_tskpri)
113#endif /* LOG_GET_PRI_ENTER */
114
115#ifndef LOG_GET_PRI_LEAVE
116#define LOG_GET_PRI_LEAVE(ercd, tskpri)
117#endif /* LOG_GET_PRI_LEAVE */
118
119#ifndef LOG_GET_INF_ENTER
120#define LOG_GET_INF_ENTER(p_exinf)
121#endif /* LOG_GET_INF_ENTER */
122
123#ifndef LOG_GET_INF_LEAVE
124#define LOG_GET_INF_LEAVE(ercd, exinf)
125#endif /* LOG_GET_INF_LEAVE */
126
127/*
128 * タスクの生成
129 */
130#ifdef TOPPERS_cre_tsk
131
132ER
133cre_tsk(ID tskid, const T_CTSK *pk_ctsk)
134{
135 TCB *p_tcb;
136 TINIB *p_tinib;
137 ATR tskatr;
138 STK_T *stk;
139 ER ercd;
140
141 LOG_CRE_TSK_ENTER(tskid, pk_ctsk);
142 CHECK_INIRTN();
143 CHECK_TSKID(tskid);
144 CHECK_RSATR(pk_ctsk->tskatr, TA_ACT|TARGET_TSKATR);
145 CHECK_ALIGN_FUNC(pk_ctsk->task);
146 CHECK_NONNULL_FUNC(pk_ctsk->task);
147 CHECK_TPRI(pk_ctsk->itskpri);
148 CHECK_STKSZ_MIN(pk_ctsk->stksz);
149 CHECK_ALIGN_STKSZ(pk_ctsk->stksz);
150 if (pk_ctsk->stk != NULL) {
151 CHECK_ALIGN_STACK(pk_ctsk->stk);
152 }
153 tskatr = pk_ctsk->tskatr;
154 stk = pk_ctsk->stk;
155 p_tcb = get_tcb_self(tskid);
156
157 if (p_tcb->p_tinib->tskatr != TA_NOEXS) {
158 ercd = E_OBJ;
159 }
160 else if ((ercd = target_check_ctsk(tskid, pk_ctsk)) == E_OK) {
161 if (stk == NULL) {
162 stk = kernel_malloc(pk_ctsk->stksz);
163 }
164 if (stk == NULL) {
165 ercd = E_NOMEM;
166 }
167 else {
168 p_tinib = (TINIB *)(p_tcb->p_tinib);
169 p_tinib->tskatr = tskatr;
170 p_tinib->exinf = pk_ctsk->exinf;
171 p_tinib->task = pk_ctsk->task;
172 p_tinib->ipriority = INT_PRIORITY(pk_ctsk->itskpri);
173#ifdef USE_TSKINICTXB
174 init_tskinictxb(&(p_tinib->tskinictxb), stk, pk_ctsk);
175#else /* USE_TSKINICTXB */
176 p_tinib->stksz = pk_ctsk->stksz;
177 p_tinib->stk = stk;
178#endif /* USE_TSKINICTXB */
179 p_tinib->texatr = TA_NULL;
180 p_tinib->texrtn = NULL;
181
182 p_tcb->actque = false;
183 make_dormant(p_tcb);
184 if ((p_tcb->p_tinib->tskatr & TA_ACT) != 0U) {
185 make_active(p_tcb);
186 }
187 }
188 }
189
190 error_exit:
191 LOG_CRE_TSK_LEAVE(ercd);
192 return(ercd);
193}
194
195#endif /* TOPPERS_cre_tsk */
196
197/*
198 * タスクの起動
199 */
200#ifdef TOPPERS_act_tsk
201
202ER
203act_tsk(ID tskid)
204{
205 TCB *p_tcb;
206 ER ercd;
207
208 LOG_ACT_TSK_ENTER(tskid);
209 CHECK_TSKCTX_UNL();
210 CHECK_TSKID_SELF(tskid);
211 p_tcb = get_tcb_self(tskid);
212 CHECK_NOEXS(p_tcb->p_tinib->tskatr);
213
214 t_lock_cpu();
215 if (TSTAT_DORMANT(p_tcb->tstat)) {
216 if (make_active(p_tcb)) {
217 dispatch();
218 }
219 ercd = E_OK;
220 }
221 else if (!(p_tcb->actque)) {
222 p_tcb->actque = true;
223 ercd = E_OK;
224 }
225 else {
226 ercd = E_QOVR;
227 }
228 t_unlock_cpu();
229
230 error_exit:
231 LOG_ACT_TSK_LEAVE(ercd);
232 return(ercd);
233}
234
235#endif /* TOPPERS_act_tsk */
236
237/*
238 * タスクの起動(非タスクコンテキスト用)
239 */
240#ifdef TOPPERS_iact_tsk
241
242ER
243iact_tsk(ID tskid)
244{
245 TCB *p_tcb;
246 ER ercd;
247
248 LOG_IACT_TSK_ENTER(tskid);
249 CHECK_INTCTX_UNL();
250 CHECK_TSKID(tskid);
251 p_tcb = get_tcb(tskid);
252 CHECK_NOEXS(p_tcb->p_tinib->tskatr);
253
254 i_lock_cpu();
255 if (TSTAT_DORMANT(p_tcb->tstat)) {
256 if (make_active(p_tcb)) {
257 reqflg = true;
258 }
259 ercd = E_OK;
260 }
261 else if (!(p_tcb->actque)) {
262 p_tcb->actque = true;
263 ercd = E_OK;
264 }
265 else {
266 ercd = E_QOVR;
267 }
268 i_unlock_cpu();
269
270 error_exit:
271 LOG_IACT_TSK_LEAVE(ercd);
272 return(ercd);
273}
274
275#endif /* TOPPERS_iact_tsk */
276
277/*
278 * タスク起動要求のキャンセル
279 */
280#ifdef TOPPERS_can_act
281
282ER_UINT
283can_act(ID tskid)
284{
285 TCB *p_tcb;
286 ER_UINT ercd;
287
288 LOG_CAN_ACT_ENTER(tskid);
289 CHECK_TSKCTX_UNL();
290 CHECK_TSKID_SELF(tskid);
291 p_tcb = get_tcb_self(tskid);
292 CHECK_NOEXS(p_tcb->p_tinib->tskatr);
293
294 t_lock_cpu();
295 ercd = p_tcb->actque ? 1 : 0;
296 p_tcb->actque = false;
297 t_unlock_cpu();
298
299 error_exit:
300 LOG_CAN_ACT_LEAVE(ercd);
301 return(ercd);
302}
303
304#endif /* TOPPERS_can_act */
305
306/*
307 * 自タスクの終了
308 */
309#ifdef TOPPERS_ext_tsk
310
311ER
312ext_tsk(void)
313{
314 ER ercd;
315
316 LOG_EXT_TSK_ENTER();
317 CHECK_TSKCTX();
318
319 if (t_sense_lock()) {
320 /*
321 * CPUロック状態でext_tskが呼ばれた場合は,CPUロックを解除し
322 * てからタスクを終了する.実装上は,サービスコール内でのCPU
323 * ロックを省略すればよいだけ.
324 */
325 }
326 else {
327 t_lock_cpu();
328 }
329 if (disdsp) {
330 /*
331 * ディスパッチ禁止状態でext_tskが呼ばれた場合は,ディスパッ
332 * チ許可状態にしてからタスクを終了する.
333 */
334 disdsp = false;
335 }
336 if (!ipmflg) {
337 /*
338 * 割込み優先度マスク(IPM)がTIPM_ENAALL以外の状態でext_tsk
339 * が呼ばれた場合は,IPMをTIPM_ENAALLにしてからタスクを終了す
340 * る.
341 */
342 t_set_ipm(TIPM_ENAALL);
343 ipmflg = true;
344 }
345 dspflg = true;
346
347 (void) make_non_runnable(p_runtsk);
348 make_dormant(p_runtsk);
349 if (p_runtsk->actque) {
350 p_runtsk->actque = false;
351 (void) make_active(p_runtsk);
352 }
353 exit_and_dispatch();
354 ercd = E_SYS;
355
356 error_exit:
357 LOG_EXT_TSK_LEAVE(ercd);
358 return(ercd);
359}
360
361#endif /* TOPPERS_ext_tsk */
362
363/*
364 * タスクの強制終了
365 */
366#ifdef TOPPERS_ter_tsk
367
368ER
369ter_tsk(ID tskid)
370{
371 TCB *p_tcb;
372 ER ercd;
373
374 LOG_TER_TSK_ENTER(tskid);
375 CHECK_TSKCTX_UNL();
376 CHECK_TSKID(tskid);
377 p_tcb = get_tcb(tskid);
378 CHECK_NOEXS(p_tcb->p_tinib->tskatr);
379 CHECK_NONSELF(p_tcb);
380
381 t_lock_cpu();
382 if (TSTAT_DORMANT(p_tcb->tstat)) {
383 ercd = E_OBJ;
384 }
385 else {
386 if (TSTAT_RUNNABLE(p_tcb->tstat)) {
387 /*
388 * p_tcbは自タスクでないため,(シングルプロセッサでは)実
389 * 行状態でなく,make_non_runnable(p_tcb)でタスクディスパッ
390 * チが必要になることはない.
391 */
392 (void) make_non_runnable(p_tcb);
393 }
394 else if (TSTAT_WAITING(p_tcb->tstat)) {
395 wait_dequeue_wobj(p_tcb);
396 wait_dequeue_tmevtb(p_tcb);
397 }
398 make_dormant(p_tcb);
399 if (p_tcb->actque) {
400 p_tcb->actque = false;
401 if (make_active(p_tcb)) {
402 dispatch();
403 }
404 }
405 ercd = E_OK;
406 }
407 t_unlock_cpu();
408
409 error_exit:
410 LOG_TER_TSK_LEAVE(ercd);
411 return(ercd);
412}
413
414#endif /* TOPPERS_ter_tsk */
415
416/*
417 * タスクのベース優先度の変更
418 */
419#ifdef TOPPERS_chg_pri
420
421ER
422chg_pri(ID tskid, PRI tskpri)
423{
424 TCB *p_tcb;
425 uint_t newpri;
426 ER ercd;
427
428 LOG_CHG_PRI_ENTER(tskid, tskpri);
429 CHECK_TSKCTX_UNL();
430 CHECK_TSKID_SELF(tskid);
431 CHECK_TPRI_INI(tskpri);
432 p_tcb = get_tcb_self(tskid);
433 CHECK_NOEXS(p_tcb->p_tinib->tskatr);
434 newpri = (tskpri == TPRI_INI) ? p_tcb->p_tinib->ipriority
435 : INT_PRIORITY(tskpri);
436
437 t_lock_cpu();
438 if (TSTAT_DORMANT(p_tcb->tstat)) {
439 ercd = E_OBJ;
440 }
441 else {
442 if (change_priority(p_tcb, newpri)) {
443 dispatch();
444 }
445 ercd = E_OK;
446 }
447 t_unlock_cpu();
448
449 error_exit:
450 LOG_CHG_PRI_LEAVE(ercd);
451 return(ercd);
452}
453
454#endif /* TOPPERS_chg_pri */
455
456/*
457 * タスク優先度の参照
458 */
459#ifdef TOPPERS_get_pri
460
461ER
462get_pri(ID tskid, PRI *p_tskpri)
463{
464 TCB *p_tcb;
465 ER ercd;
466
467 LOG_GET_PRI_ENTER(tskid, p_tskpri);
468 CHECK_TSKCTX_UNL();
469 CHECK_TSKID_SELF(tskid);
470 p_tcb = get_tcb_self(tskid);
471 CHECK_NOEXS(p_tcb->p_tinib->tskatr);
472
473 t_lock_cpu();
474 if (TSTAT_DORMANT(p_tcb->tstat)) {
475 ercd = E_OBJ;
476 }
477 else {
478 *p_tskpri = EXT_TSKPRI(p_tcb->priority);
479 ercd = E_OK;
480 }
481 t_unlock_cpu();
482
483 error_exit:
484 LOG_GET_PRI_LEAVE(ercd, *p_tskpri);
485 return(ercd);
486}
487
488#endif /* TOPPERS_get_pri */
489
490/*
491 * 自タスクの拡張情報の参照
492 */
493#ifdef TOPPERS_get_inf
494
495ER
496get_inf(intptr_t *p_exinf)
497{
498 ER ercd;
499
500 LOG_GET_INF_ENTER(p_exinf);
501 CHECK_TSKCTX_UNL();
502
503 t_lock_cpu();
504 *p_exinf = p_runtsk->p_tinib->exinf;
505 ercd = E_OK;
506 t_unlock_cpu();
507
508 error_exit:
509 LOG_GET_INF_LEAVE(ercd, *p_exinf);
510 return(ercd);
511}
512
513#endif /* TOPPERS_get_inf */
Note: See TracBrowser for help on using the repository browser.