source: rubycfg_asp/trunk/asp_dcre/kernel/task_manage.c@ 315

Last change on this file since 315 was 315, checked in by coas-nagasima, 7 years ago

SVNプロパティを設定

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