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

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

文字コードを設定

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 12.5 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$
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
128#ifndef TARGET_MIN_STKSZ
129#define TARGET_MIN_STKSZ 1U /* 未定義の場合は0でないことをチェック */
130#endif /* TARGET_MIN_STKSZ */
131
132ER_UINT
133acre_tsk(const T_CTSK *pk_ctsk)
134{
135 TCB *p_tcb;
136 TINIB *p_tinib;
137 ATR tskatr;
138 TASK task;
139 PRI itskpri;
140 size_t stksz;
141 STK_T *stk;
142 ER ercd;
143
144 LOG_ACRE_TSK_ENTER(pk_ctsk);
145 CHECK_TSKCTX_UNL();
146
147 tskatr = pk_ctsk->tskatr;
148 task = pk_ctsk->task;
149 itskpri = pk_ctsk->itskpri;
150 stksz = pk_ctsk->stksz;
151 stk = pk_ctsk->stk;
152
153 CHECK_RSATR(tskatr, TA_ACT|TA_NOACTQUE|TARGET_TSKATR);
154 CHECK_PAR(FUNC_ALIGN(task));
155 CHECK_PAR(FUNC_NONNULL(task));
156 CHECK_PAR(VALID_TPRI(itskpri));
157 CHECK_PAR(stksz >= TARGET_MIN_STKSZ);
158 if (stk != NULL) {
159 CHECK_PAR(STKSZ_ALIGN(stksz));
160 CHECK_PAR(STACK_ALIGN(stk));
161 }
162
163 lock_cpu();
164 if (queue_empty(&free_tcb)) {
165 ercd = E_NOID;
166 }
167 else {
168 if (stk == NULL) {
169 stksz = ROUND_STK_T(stksz);
170 stk = kernel_malloc(stksz);
171 tskatr |= TA_MEMALLOC;
172 }
173 if (stk == NULL) {
174 ercd = E_NOMEM;
175 }
176 else {
177 p_tcb = ((TCB *) queue_delete_next(&free_tcb));
178 p_tinib = (TINIB *)(p_tcb->p_tinib);
179 p_tinib->tskatr = tskatr;
180 p_tinib->exinf = pk_ctsk->exinf;
181 p_tinib->task = task;
182 p_tinib->ipriority = INT_PRIORITY(itskpri);
183#ifdef USE_TSKINICTXB
184 init_tskinictxb(&(p_tinib->tskinictxb), stksz, stk);
185#else /* USE_TSKINICTXB */
186 p_tinib->stksz = stksz;
187 p_tinib->stk = stk;
188#endif /* USE_TSKINICTXB */
189
190 p_tcb->actque = false;
191 make_dormant(p_tcb);
192 if ((p_tcb->p_tinib->tskatr & TA_ACT) != 0U) {
193 make_active(p_tcb);
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 kernel_free(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();
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 newbpri = p_tcb->p_tinib->ipriority; /*[NGKI1199]*/
426 }
427 else {
428 CHECK_PAR(VALID_TPRI(tskpri)); /*[NGKI1188]*/
429 newbpri = INT_PRIORITY(tskpri);
430 }
431
432 lock_cpu();
433 if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
434 ercd = E_NOEXS; /*[NGKI1189]*/
435 }
436 else if (TSTAT_DORMANT(p_tcb->tstat)) {
437 ercd = E_OBJ; /*[NGKI1191]*/
438 }
439 else if ((p_tcb->p_lastmtx != NULL || TSTAT_WAIT_MTX(p_tcb->tstat))
440 && !((*mtxhook_check_ceilpri)(p_tcb, newbpri))) {
441 ercd = E_ILUSE; /*[NGKI1201]*/
442 }
443 else {
444 p_tcb->bpriority = newbpri; /*[NGKI1192]*/
445 if (p_tcb->p_lastmtx == NULL || !((*mtxhook_scan_ceilmtx)(p_tcb))) {
446 change_priority(p_tcb, newbpri, false); /*[NGKI1193]*/
447 if (p_runtsk != p_schedtsk) {
448 dispatch();
449 } /*[NGKI1197]*/
450 }
451 ercd = E_OK;
452 }
453 unlock_cpu();
454
455 error_exit:
456 LOG_CHG_PRI_LEAVE(ercd);
457 return(ercd);
458}
459
460#endif /* TOPPERS_chg_pri */
461
462/*
463 * タスク優先度の参照[NGKI1202]
464 */
465#ifdef TOPPERS_get_pri
466
467ER
468get_pri(ID tskid, PRI *p_tskpri)
469{
470 TCB *p_tcb;
471 ER ercd;
472
473 LOG_GET_PRI_ENTER(tskid, p_tskpri);
474 CHECK_TSKCTX_UNL(); /*[NGKI1203][NGKI1204]*/
475 if (tskid == TSK_SELF) {
476 p_tcb = p_runtsk; /*[NGKI1211]*/
477 }
478 else {
479 CHECK_ID(VALID_TSKID(tskid)); /*[NGKI1205]*/
480 p_tcb = get_tcb(tskid);
481 }
482
483 lock_cpu();
484 if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
485 ercd = E_NOEXS; /*[NGKI1206]*/
486 }
487 else if (TSTAT_DORMANT(p_tcb->tstat)) {
488 ercd = E_OBJ; /*[NGKI1209]*/
489 }
490 else {
491 *p_tskpri = EXT_TSKPRI(p_tcb->priority); /*[NGKI1210]*/
492 ercd = E_OK;
493 }
494 unlock_cpu();
495
496 error_exit:
497 LOG_GET_PRI_LEAVE(ercd, p_tskpri);
498 return(ercd);
499}
500
501#endif /* TOPPERS_get_pri */
502
503/*
504 * 自タスクの拡張情報の参照[NGKI1212]
505 */
506#ifdef TOPPERS_get_inf
507
508ER
509get_inf(intptr_t *p_exinf)
510{
511 ER ercd;
512
513 LOG_GET_INF_ENTER(p_exinf);
514 CHECK_TSKCTX_UNL(); /*[NGKI1213][NGKI1214]*/
515
516 lock_cpu();
517 *p_exinf = p_runtsk->p_tinib->exinf; /*[NGKI1216]*/
518 ercd = E_OK;
519 unlock_cpu();
520
521 error_exit:
522 LOG_GET_INF_LEAVE(ercd, p_exinf);
523 return(ercd);
524}
525
526#endif /* TOPPERS_get_inf */
Note: See TracBrowser for help on using the repository browser.