source: azure_iot_hub/trunk/asp3_dcre/kernel/task_manage.c@ 389

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

ビルドが通るよう更新

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 12.6 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 if (p_runtsk != p_schedtsk) {
195 dispatch();
196 }
197 }
198 ercd = TSKID(p_tcb);
199 }
200 }
201 unlock_cpu();
202
203 error_exit:
204 LOG_ACRE_TSK_LEAVE(ercd);
205 return(ercd);
206}
207
208#endif /* TOPPERS_acre_tsk */
209
210/*
211 * タスクの削除[NGKI1100]
212 */
213#ifdef TOPPERS_del_tsk
214
215ER
216del_tsk(ID tskid)
217{
218 TCB *p_tcb;
219 TINIB *p_tinib;
220 ER ercd;
221
222 LOG_DEL_TSK_ENTER(tskid);
223 CHECK_TSKCTX_UNL(); /*[NGKI1101][NGKI1102]*/
224 CHECK_ID(VALID_TSKID(tskid)); /*[NGKI1103]*/
225 p_tcb = get_tcb(tskid);
226
227 lock_cpu();
228 if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
229 ercd = E_NOEXS; /*[NGKI1104]*/
230 }
231 else if (tskid <= tmax_stskid || !TSTAT_DORMANT(p_tcb->tstat)) {
232 ercd = E_OBJ; /*[NGKI1106][NGKI1107]*/
233 }
234 else {
235 p_tinib = (TINIB *)(p_tcb->p_tinib);
236#ifdef USE_TSKINICTXB
237 term_tskinictxb(&(p_tinib->tskinictxb));
238#else /* USE_TSKINICTXB */
239 if ((p_tinib->tskatr & TA_MEMALLOC) != 0U) { /*[NGKI1109]*/
240 kernel_free(p_tinib->stk);
241 }
242#endif /* USE_TSKINICTXB */
243 p_tinib->tskatr = TA_NOEXS; /*[NGKI1108]*/
244 queue_insert_prev(&free_tcb, &(p_tcb->task_queue));
245 ercd = E_OK;
246 }
247 unlock_cpu();
248
249 error_exit:
250 LOG_DEL_TSK_LEAVE(ercd);
251 return(ercd);
252}
253
254#endif /* TOPPERS_del_tsk */
255
256/*
257 * タスクの起動[NGKI3529]
258 */
259#ifdef TOPPERS_act_tsk
260
261ER
262act_tsk(ID tskid)
263{
264 TCB *p_tcb;
265 ER ercd;
266
267 LOG_ACT_TSK_ENTER(tskid);
268 CHECK_UNL(); /*[NGKI1114]*/
269 if (tskid == TSK_SELF && !sense_context()) {
270 p_tcb = p_runtsk; /*[NGKI1121]*/
271 }
272 else {
273 CHECK_ID(VALID_TSKID(tskid)); /*[NGKI1115]*/
274 p_tcb = get_tcb(tskid);
275 }
276
277 lock_cpu();
278 if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
279 ercd = E_NOEXS; /*[NGKI1116]*/
280 }
281 else if (TSTAT_DORMANT(p_tcb->tstat)) {
282 make_active(p_tcb); /*[NGKI1118]*/
283 if (p_runtsk != p_schedtsk) {
284 if (!sense_context()) {
285 dispatch();
286 }
287 else {
288 request_dispatch();
289 }
290 }
291 ercd = E_OK;
292 }
293 else if ((p_tcb->p_tinib->tskatr & TA_NOACTQUE) != 0U || p_tcb->actque) {
294 ercd = E_QOVR; /*[NGKI3528]*/
295 }
296 else {
297 p_tcb->actque = true; /*[NGKI3527]*/
298 ercd = E_OK;
299 }
300 unlock_cpu();
301
302 error_exit:
303 LOG_ACT_TSK_LEAVE(ercd);
304 return(ercd);
305}
306
307#endif /* TOPPERS_act_tsk */
308
309/*
310 * タスク起動要求のキャンセル[NGKI1138]
311 */
312#ifdef TOPPERS_can_act
313
314ER_UINT
315can_act(ID tskid)
316{
317 TCB *p_tcb;
318 ER_UINT ercd;
319
320 LOG_CAN_ACT_ENTER(tskid);
321 CHECK_TSKCTX_UNL(); /*[NGKI1139][NGKI1140]*/
322 if (tskid == TSK_SELF) {
323 p_tcb = p_runtsk; /*[NGKI1146]*/
324 }
325 else {
326 CHECK_ID(VALID_TSKID(tskid)); /*[NGKI1141]*/
327 p_tcb = get_tcb(tskid);
328 }
329
330 lock_cpu();
331 if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
332 ercd = E_NOEXS; /*[NGKI1142]*/
333 }
334 else {
335 ercd = p_tcb->actque ? 1 : 0; /*[NGKI1144]*/
336 p_tcb->actque = false; /*[NGKI1144]*/
337 }
338 unlock_cpu();
339
340 error_exit:
341 LOG_CAN_ACT_LEAVE(ercd);
342 return(ercd);
343}
344
345#endif /* TOPPERS_can_act */
346
347/*
348 * タスク状態の参照[NGKI3613]
349 */
350#ifdef TOPPERS_get_tst
351
352ER
353get_tst(ID tskid, STAT *p_tskstat)
354{
355 TCB *p_tcb;
356 uint_t tstat;
357 ER ercd;
358
359 LOG_GET_TST_ENTER(tskid, p_tskstat);
360 CHECK_TSKCTX_UNL(); /*[NGKI3614][NGKI3615]*/
361 if (tskid == TSK_SELF) {
362 p_tcb = p_runtsk; /*[NGKI3621]*/
363 }
364 else {
365 CHECK_ID(VALID_TSKID(tskid)); /*[NGKI3616]*/
366 p_tcb = get_tcb(tskid);
367 }
368
369 lock_cpu();
370 tstat = p_tcb->tstat;
371 if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
372 ercd = E_NOEXS; /*[NGKI3617]*/
373 }
374 else {
375 if (TSTAT_DORMANT(tstat)) { /*[NGKI3620]*/
376 *p_tskstat = TTS_DMT;
377 }
378 else if (TSTAT_SUSPENDED(tstat)) {
379 if (TSTAT_WAITING(tstat)) {
380 *p_tskstat = TTS_WAS;
381 }
382 else {
383 *p_tskstat = TTS_SUS;
384 }
385 }
386 else if (TSTAT_WAITING(tstat)) {
387 *p_tskstat = TTS_WAI;
388 }
389 else if (p_tcb == p_runtsk) {
390 *p_tskstat = TTS_RUN;
391 }
392 else {
393 *p_tskstat = TTS_RDY;
394 }
395 ercd = E_OK;
396 }
397 unlock_cpu();
398
399 error_exit:
400 LOG_GET_TST_LEAVE(ercd, p_tskstat);
401 return(ercd);
402}
403
404#endif /* TOPPERS_get_tst */
405
406/*
407 * タスクのベース優先度の変更[NGKI1183]
408 */
409#ifdef TOPPERS_chg_pri
410
411ER
412chg_pri(ID tskid, PRI tskpri)
413{
414 TCB *p_tcb;
415 uint_t newbpri;
416 ER ercd;
417
418 LOG_CHG_PRI_ENTER(tskid, tskpri);
419 CHECK_TSKCTX_UNL(); /*[NGKI1184][NGKI1185]*/
420 if (tskid == TSK_SELF) {
421 p_tcb = p_runtsk; /*[NGKI1198]*/
422 }
423 else {
424 CHECK_ID(VALID_TSKID(tskid)); /*[NGKI1187]*/
425 p_tcb = get_tcb(tskid);
426 }
427 if (tskpri == TPRI_INI) {
428 newbpri = p_tcb->p_tinib->ipriority; /*[NGKI1199]*/
429 }
430 else {
431 CHECK_PAR(VALID_TPRI(tskpri)); /*[NGKI1188]*/
432 newbpri = INT_PRIORITY(tskpri);
433 }
434
435 lock_cpu();
436 if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
437 ercd = E_NOEXS; /*[NGKI1189]*/
438 }
439 else if (TSTAT_DORMANT(p_tcb->tstat)) {
440 ercd = E_OBJ; /*[NGKI1191]*/
441 }
442 else if ((p_tcb->p_lastmtx != NULL || TSTAT_WAIT_MTX(p_tcb->tstat))
443 && !((*mtxhook_check_ceilpri)(p_tcb, newbpri))) {
444 ercd = E_ILUSE; /*[NGKI1201]*/
445 }
446 else {
447 p_tcb->bpriority = newbpri; /*[NGKI1192]*/
448 if (p_tcb->p_lastmtx == NULL || !((*mtxhook_scan_ceilmtx)(p_tcb))) {
449 change_priority(p_tcb, newbpri, false); /*[NGKI1193]*/
450 if (p_runtsk != p_schedtsk) {
451 dispatch();
452 } /*[NGKI1197]*/
453 }
454 ercd = E_OK;
455 }
456 unlock_cpu();
457
458 error_exit:
459 LOG_CHG_PRI_LEAVE(ercd);
460 return(ercd);
461}
462
463#endif /* TOPPERS_chg_pri */
464
465/*
466 * タスク優先度の参照[NGKI1202]
467 */
468#ifdef TOPPERS_get_pri
469
470ER
471get_pri(ID tskid, PRI *p_tskpri)
472{
473 TCB *p_tcb;
474 ER ercd;
475
476 LOG_GET_PRI_ENTER(tskid, p_tskpri);
477 CHECK_TSKCTX_UNL(); /*[NGKI1203][NGKI1204]*/
478 if (tskid == TSK_SELF) {
479 p_tcb = p_runtsk; /*[NGKI1211]*/
480 }
481 else {
482 CHECK_ID(VALID_TSKID(tskid)); /*[NGKI1205]*/
483 p_tcb = get_tcb(tskid);
484 }
485
486 lock_cpu();
487 if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
488 ercd = E_NOEXS; /*[NGKI1206]*/
489 }
490 else if (TSTAT_DORMANT(p_tcb->tstat)) {
491 ercd = E_OBJ; /*[NGKI1209]*/
492 }
493 else {
494 *p_tskpri = EXT_TSKPRI(p_tcb->priority); /*[NGKI1210]*/
495 ercd = E_OK;
496 }
497 unlock_cpu();
498
499 error_exit:
500 LOG_GET_PRI_LEAVE(ercd, p_tskpri);
501 return(ercd);
502}
503
504#endif /* TOPPERS_get_pri */
505
506/*
507 * 自タスクの拡張情報の参照[NGKI1212]
508 */
509#ifdef TOPPERS_get_inf
510
511ER
512get_inf(intptr_t *p_exinf)
513{
514 ER ercd;
515
516 LOG_GET_INF_ENTER(p_exinf);
517 CHECK_TSKCTX_UNL(); /*[NGKI1213][NGKI1214]*/
518
519 lock_cpu();
520 *p_exinf = p_runtsk->p_tinib->exinf; /*[NGKI1216]*/
521 ercd = E_OK;
522 unlock_cpu();
523
524 error_exit:
525 LOG_GET_INF_LEAVE(ercd, p_exinf);
526 return(ercd);
527}
528
529#endif /* TOPPERS_get_inf */
Note: See TracBrowser for help on using the repository browser.