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

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

ASPカーネル 動的生成機能拡張パッケージへの追従。

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