source: EcnlProtoTool/trunk/asp3_dcre/kernel/task_manage.c@ 429

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

ASP3, TINET, mbed を更新

  • Property svn:eol-style set to native
  • 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-2018 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$
41 */
42
43/*
44 * タスク管理機能
45 */
46
47#include "kernel_impl.h"
48#include "check.h"
49#include "task.h"
50#include "taskhook.h"
51#include "wait.h"
52
53/*
54 * トレースログマクロのデフォルト定義
55 */
56#ifndef LOG_ACRE_TSK_ENTER
57#define LOG_ACRE_TSK_ENTER(pk_ctsk)
58#endif /* LOG_ACRE_TSK_ENTER */
59
60#ifndef LOG_ACRE_TSK_LEAVE
61#define LOG_ACRE_TSK_LEAVE(ercd)
62#endif /* LOG_ACRE_TSK_LEAVE */
63
64#ifndef LOG_DEL_TSK_ENTER
65#define LOG_DEL_TSK_ENTER(tskid)
66#endif /* LOG_DEL_TSK_ENTER */
67
68#ifndef LOG_DEL_TSK_LEAVE
69#define LOG_DEL_TSK_LEAVE(ercd)
70#endif /* LOG_DEL_TSK_LEAVE */
71
72#ifndef LOG_ACT_TSK_ENTER
73#define LOG_ACT_TSK_ENTER(tskid)
74#endif /* LOG_ACT_TSK_ENTER */
75
76#ifndef LOG_ACT_TSK_LEAVE
77#define LOG_ACT_TSK_LEAVE(ercd)
78#endif /* LOG_ACT_TSK_LEAVE */
79
80#ifndef LOG_CAN_ACT_ENTER
81#define LOG_CAN_ACT_ENTER(tskid)
82#endif /* LOG_CAN_ACT_ENTER */
83
84#ifndef LOG_CAN_ACT_LEAVE
85#define LOG_CAN_ACT_LEAVE(ercd)
86#endif /* LOG_CAN_ACT_LEAVE */
87
88#ifndef LOG_GET_TST_ENTER
89#define LOG_GET_TST_ENTER(tskid, p_tskstat)
90#endif /* LOG_GET_TST_ENTER */
91
92#ifndef LOG_GET_TST_LEAVE
93#define LOG_GET_TST_LEAVE(ercd, p_tskstat)
94#endif /* LOG_GET_TST_LEAVE */
95
96#ifndef LOG_CHG_PRI_ENTER
97#define LOG_CHG_PRI_ENTER(tskid, tskpri)
98#endif /* LOG_CHG_PRI_ENTER */
99
100#ifndef LOG_CHG_PRI_LEAVE
101#define LOG_CHG_PRI_LEAVE(ercd)
102#endif /* LOG_CHG_PRI_LEAVE */
103
104#ifndef LOG_GET_PRI_ENTER
105#define LOG_GET_PRI_ENTER(tskid, p_tskpri)
106#endif /* LOG_GET_PRI_ENTER */
107
108#ifndef LOG_GET_PRI_LEAVE
109#define LOG_GET_PRI_LEAVE(ercd, p_tskpri)
110#endif /* LOG_GET_PRI_LEAVE */
111
112#ifndef LOG_GET_INF_ENTER
113#define LOG_GET_INF_ENTER(p_exinf)
114#endif /* LOG_GET_INF_ENTER */
115
116#ifndef LOG_GET_INF_LEAVE
117#define LOG_GET_INF_LEAVE(ercd, p_exinf)
118#endif /* LOG_GET_INF_LEAVE */
119
120/*
121 * タスクの生成
122 *
123 * pk_ctsk->exinfは,エラーチェックをせず,一度しか参照しないため,ロー
124 * カル変数にコピーする必要がない(途中で書き換わっても支障がない).
125 */
126#ifdef TOPPERS_acre_tsk
127
128ER_UINT
129acre_tsk(const T_CTSK *pk_ctsk)
130{
131 TCB *p_tcb;
132 TINIB *p_tinib;
133 ATR tskatr;
134 TASK task;
135 PRI itskpri;
136 size_t stksz;
137 STK_T *stk;
138 ER ercd;
139
140 LOG_ACRE_TSK_ENTER(pk_ctsk);
141 CHECK_TSKCTX_UNL();
142
143 tskatr = pk_ctsk->tskatr;
144 task = pk_ctsk->task;
145 itskpri = pk_ctsk->itskpri;
146 stksz = pk_ctsk->stksz;
147 stk = pk_ctsk->stk;
148
149 CHECK_VALIDATR(tskatr, TA_ACT|TA_NOACTQUE|TARGET_TSKATR);
150 CHECK_PAR(FUNC_ALIGN(task));
151 CHECK_PAR(FUNC_NONNULL(task));
152 CHECK_PAR(VALID_TPRI(itskpri));
153 CHECK_PAR(stksz >= TARGET_MIN_STKSZ);
154 if (stk != NULL) {
155 CHECK_PAR(STKSZ_ALIGN(stksz));
156 CHECK_PAR(STACK_ALIGN(stk));
157 }
158
159 lock_cpu();
160 if (queue_empty(&free_tcb)) {
161 ercd = E_NOID;
162 }
163 else {
164 if (stk == NULL) {
165 stksz = ROUND_STK_T(stksz);
166 stk = malloc_mpk(stksz);
167 tskatr |= TA_MEMALLOC;
168 }
169 if (stk == NULL) {
170 ercd = E_NOMEM;
171 }
172 else {
173 p_tcb = ((TCB *) queue_delete_next(&free_tcb));
174 p_tinib = (TINIB *)(p_tcb->p_tinib);
175 p_tinib->tskatr = tskatr;
176 p_tinib->exinf = pk_ctsk->exinf;
177 p_tinib->task = task;
178 p_tinib->ipriority = INT_PRIORITY(itskpri);
179#ifdef USE_TSKINICTXB
180 init_tskinictxb(&(p_tinib->tskinictxb), stksz, stk);
181#else /* USE_TSKINICTXB */
182 p_tinib->stksz = stksz;
183 p_tinib->stk = stk;
184#endif /* USE_TSKINICTXB */
185
186 p_tcb->actque = false;
187 p_tcb->p_lastmtx = NULL;
188 make_dormant(p_tcb);
189 if ((p_tcb->p_tinib->tskatr & TA_ACT) != 0U) {
190 make_active(p_tcb);
191 if (p_runtsk != p_schedtsk) {
192 dispatch();
193 }
194 }
195 ercd = TSKID(p_tcb);
196 }
197 }
198 unlock_cpu();
199
200 error_exit:
201 LOG_ACRE_TSK_LEAVE(ercd);
202 return(ercd);
203}
204
205#endif /* TOPPERS_acre_tsk */
206
207/*
208 * タスクの削除[NGKI1100]
209 */
210#ifdef TOPPERS_del_tsk
211
212ER
213del_tsk(ID tskid)
214{
215 TCB *p_tcb;
216 TINIB *p_tinib;
217 ER ercd;
218
219 LOG_DEL_TSK_ENTER(tskid);
220 CHECK_TSKCTX_UNL(); /*[NGKI1101][NGKI1102]*/
221 CHECK_ID(VALID_TSKID(tskid)); /*[NGKI1103]*/
222 p_tcb = get_tcb(tskid);
223
224 lock_cpu();
225 if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
226 ercd = E_NOEXS; /*[NGKI1104]*/
227 }
228 else if (tskid <= tmax_stskid || !TSTAT_DORMANT(p_tcb->tstat)) {
229 ercd = E_OBJ; /*[NGKI1106][NGKI1107]*/
230 }
231 else {
232 p_tinib = (TINIB *)(p_tcb->p_tinib);
233#ifdef USE_TSKINICTXB
234 term_tskinictxb(&(p_tinib->tskinictxb));
235#else /* USE_TSKINICTXB */
236 if ((p_tinib->tskatr & TA_MEMALLOC) != 0U) { /*[NGKI1109]*/
237 free_mpk(p_tinib->stk);
238 }
239#endif /* USE_TSKINICTXB */
240 p_tinib->tskatr = TA_NOEXS; /*[NGKI1108]*/
241 queue_insert_prev(&free_tcb, &(p_tcb->task_queue));
242 ercd = E_OK;
243 }
244 unlock_cpu();
245
246 error_exit:
247 LOG_DEL_TSK_LEAVE(ercd);
248 return(ercd);
249}
250
251#endif /* TOPPERS_del_tsk */
252
253/*
254 * タスクの起動[NGKI3529]
255 */
256#ifdef TOPPERS_act_tsk
257
258ER
259act_tsk(ID tskid)
260{
261 TCB *p_tcb;
262 ER ercd;
263
264 LOG_ACT_TSK_ENTER(tskid);
265 CHECK_UNL(); /*[NGKI1114]*/
266 if (tskid == TSK_SELF && !sense_context()) {
267 p_tcb = p_runtsk; /*[NGKI1121]*/
268 }
269 else {
270 CHECK_ID(VALID_TSKID(tskid)); /*[NGKI1115]*/
271 p_tcb = get_tcb(tskid);
272 }
273
274 lock_cpu();
275 if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
276 ercd = E_NOEXS; /*[NGKI1116]*/
277 }
278 else if (TSTAT_DORMANT(p_tcb->tstat)) {
279 make_active(p_tcb); /*[NGKI1118]*/
280 if (p_runtsk != p_schedtsk) {
281 if (!sense_context()) {
282 dispatch();
283 }
284 else {
285 request_dispatch_retint();
286 }
287 }
288 ercd = E_OK;
289 }
290 else if ((p_tcb->p_tinib->tskatr & TA_NOACTQUE) != 0U || p_tcb->actque) {
291 ercd = E_QOVR; /*[NGKI3528]*/
292 }
293 else {
294 p_tcb->actque = true; /*[NGKI3527]*/
295 ercd = E_OK;
296 }
297 unlock_cpu();
298
299 error_exit:
300 LOG_ACT_TSK_LEAVE(ercd);
301 return(ercd);
302}
303
304#endif /* TOPPERS_act_tsk */
305
306/*
307 * タスク起動要求のキャンセル[NGKI1138]
308 */
309#ifdef TOPPERS_can_act
310
311ER_UINT
312can_act(ID tskid)
313{
314 TCB *p_tcb;
315 ER_UINT ercd;
316
317 LOG_CAN_ACT_ENTER(tskid);
318 CHECK_TSKCTX_UNL(); /*[NGKI1139][NGKI1140]*/
319 if (tskid == TSK_SELF) {
320 p_tcb = p_runtsk; /*[NGKI1146]*/
321 }
322 else {
323 CHECK_ID(VALID_TSKID(tskid)); /*[NGKI1141]*/
324 p_tcb = get_tcb(tskid);
325 }
326
327 lock_cpu();
328 if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
329 ercd = E_NOEXS; /*[NGKI1142]*/
330 }
331 else {
332 ercd = p_tcb->actque ? 1 : 0; /*[NGKI1144]*/
333 p_tcb->actque = false; /*[NGKI1144]*/
334 }
335 unlock_cpu();
336
337 error_exit:
338 LOG_CAN_ACT_LEAVE(ercd);
339 return(ercd);
340}
341
342#endif /* TOPPERS_can_act */
343
344/*
345 * タスク状態の参照[NGKI3613]
346 */
347#ifdef TOPPERS_get_tst
348
349ER
350get_tst(ID tskid, STAT *p_tskstat)
351{
352 TCB *p_tcb;
353 uint_t tstat;
354 ER ercd;
355
356 LOG_GET_TST_ENTER(tskid, p_tskstat);
357 CHECK_TSKCTX_UNL(); /*[NGKI3614][NGKI3615]*/
358 if (tskid == TSK_SELF) {
359 p_tcb = p_runtsk; /*[NGKI3621]*/
360 }
361 else {
362 CHECK_ID(VALID_TSKID(tskid)); /*[NGKI3616]*/
363 p_tcb = get_tcb(tskid);
364 }
365
366 lock_cpu();
367 tstat = p_tcb->tstat;
368 if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
369 ercd = E_NOEXS; /*[NGKI3617]*/
370 }
371 else {
372 if (TSTAT_DORMANT(tstat)) { /*[NGKI3620]*/
373 *p_tskstat = TTS_DMT;
374 }
375 else if (TSTAT_SUSPENDED(tstat)) {
376 if (TSTAT_WAITING(tstat)) {
377 *p_tskstat = TTS_WAS;
378 }
379 else {
380 *p_tskstat = TTS_SUS;
381 }
382 }
383 else if (TSTAT_WAITING(tstat)) {
384 *p_tskstat = TTS_WAI;
385 }
386 else if (p_tcb == p_runtsk) {
387 *p_tskstat = TTS_RUN;
388 }
389 else {
390 *p_tskstat = TTS_RDY;
391 }
392 ercd = E_OK;
393 }
394 unlock_cpu();
395
396 error_exit:
397 LOG_GET_TST_LEAVE(ercd, p_tskstat);
398 return(ercd);
399}
400
401#endif /* TOPPERS_get_tst */
402
403/*
404 * タスクのベース優先度の変更[NGKI1183]
405 */
406#ifdef TOPPERS_chg_pri
407
408ER
409chg_pri(ID tskid, PRI tskpri)
410{
411 TCB *p_tcb;
412 uint_t newbpri;
413 ER ercd;
414
415 LOG_CHG_PRI_ENTER(tskid, tskpri);
416 CHECK_TSKCTX_UNL(); /*[NGKI1184][NGKI1185]*/
417 if (tskid == TSK_SELF) {
418 p_tcb = p_runtsk; /*[NGKI1198]*/
419 }
420 else {
421 CHECK_ID(VALID_TSKID(tskid)); /*[NGKI1187]*/
422 p_tcb = get_tcb(tskid);
423 }
424 if (tskpri == TPRI_INI) {
425 /*
426 * 以下の代入文は,対象タスクが未登録の場合に無効なフィールド
427 * を参照するが,その場合はnewbpriの値を使わないので,問題な
428 * い.
429 */
430 newbpri = p_tcb->p_tinib->ipriority; /*[NGKI1199]*/
431 }
432 else {
433 CHECK_PAR(VALID_TPRI(tskpri)); /*[NGKI1188]*/
434 newbpri = INT_PRIORITY(tskpri);
435 }
436
437 lock_cpu();
438 if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
439 ercd = E_NOEXS; /*[NGKI1189]*/
440 }
441 else if (TSTAT_DORMANT(p_tcb->tstat)) {
442 ercd = E_OBJ; /*[NGKI1191]*/
443 }
444 else if ((p_tcb->p_lastmtx != NULL || TSTAT_WAIT_MTX(p_tcb->tstat))
445 && !((*mtxhook_check_ceilpri)(p_tcb, newbpri))) {
446 ercd = E_ILUSE; /*[NGKI1201]*/
447 }
448 else {
449 p_tcb->bpriority = newbpri; /*[NGKI1192]*/
450 if (p_tcb->p_lastmtx == NULL || !((*mtxhook_scan_ceilmtx)(p_tcb))) {
451 change_priority(p_tcb, newbpri, false); /*[NGKI1193]*/
452 if (p_runtsk != p_schedtsk) {
453 dispatch();
454 } /*[NGKI1197]*/
455 }
456 ercd = E_OK;
457 }
458 unlock_cpu();
459
460 error_exit:
461 LOG_CHG_PRI_LEAVE(ercd);
462 return(ercd);
463}
464
465#endif /* TOPPERS_chg_pri */
466
467/*
468 * タスク優先度の参照[NGKI1202]
469 */
470#ifdef TOPPERS_get_pri
471
472ER
473get_pri(ID tskid, PRI *p_tskpri)
474{
475 TCB *p_tcb;
476 ER ercd;
477
478 LOG_GET_PRI_ENTER(tskid, p_tskpri);
479 CHECK_TSKCTX_UNL(); /*[NGKI1203][NGKI1204]*/
480 if (tskid == TSK_SELF) {
481 p_tcb = p_runtsk; /*[NGKI1211]*/
482 }
483 else {
484 CHECK_ID(VALID_TSKID(tskid)); /*[NGKI1205]*/
485 p_tcb = get_tcb(tskid);
486 }
487
488 lock_cpu();
489 if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
490 ercd = E_NOEXS; /*[NGKI1206]*/
491 }
492 else if (TSTAT_DORMANT(p_tcb->tstat)) {
493 ercd = E_OBJ; /*[NGKI1209]*/
494 }
495 else {
496 *p_tskpri = EXT_TSKPRI(p_tcb->priority); /*[NGKI1210]*/
497 ercd = E_OK;
498 }
499 unlock_cpu();
500
501 error_exit:
502 LOG_GET_PRI_LEAVE(ercd, p_tskpri);
503 return(ercd);
504}
505
506#endif /* TOPPERS_get_pri */
507
508/*
509 * 自タスクの拡張情報の参照[NGKI1212]
510 */
511#ifdef TOPPERS_get_inf
512
513ER
514get_inf(intptr_t *p_exinf)
515{
516 ER ercd;
517
518 LOG_GET_INF_ENTER(p_exinf);
519 CHECK_TSKCTX_UNL(); /*[NGKI1213][NGKI1214]*/
520
521 lock_cpu();
522 *p_exinf = p_runtsk->p_tinib->exinf; /*[NGKI1216]*/
523 ercd = E_OK;
524 unlock_cpu();
525
526 error_exit:
527 LOG_GET_INF_LEAVE(ercd, p_exinf);
528 return(ercd);
529}
530
531#endif /* TOPPERS_get_inf */
Note: See TracBrowser for help on using the repository browser.