source: UsbWattMeter/trunk/asp_dcre/kernel/task_manage.c@ 473

Last change on this file since 473 was 167, checked in by coas-nagasima, 8 years ago

MIMEにSJISを設定

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