3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Just Standard Profile Kernel
6 * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
8 * Copyright (C) 2005,2006 by Embedded and Real-Time Systems Laboratory
9 * Graduate School of Information Science, Nagoya Univ., JAPAN
11 * 上記著作権者は,以下の (1)〜(4) の条件か,Free Software Foundation
12 * によって公表されている GNU General Public License の Version 2 に記
13 * 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
14 * を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
16 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
17 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
19 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
20 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
21 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
23 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
24 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
26 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
27 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
28 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
30 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
31 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
33 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
34 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
35 * 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
36 * 接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
38 * @(#) $Id: task.c,v 1.1 2009/01/31 05:27:37 suikan Exp $
45 #include "jsp_kernel.h"
47 #include <cpu_context.h>
62 * タスクディスパッチ/タスク例外処理ルーチン起動要求フラグ
74 QUEUE ready_queue[TNUM_TPRI];
79 * ビットマップを UINT で定義しているが,ビットマップサーチ関数で優先
80 * 度が16段階以下であることを仮定している.
93 runtsk = schedtsk = NULL;
97 for (i = 0; i < TNUM_TPRI; i++) {
98 queue_initialize(&(ready_queue[i]));
102 for (i = 0; i < TNUM_TSK; i++) {
103 j = INDEX_TSK(torder_table[i]);
104 tcb = &(tcb_table[j]);
105 tcb->tinib = &(tinib_table[j]);
108 if ((tcb->tinib->tskatr & TA_ACT) != 0) {
114 #endif /* __tskini */
119 * bitmap 内の 1 のビットの内,最も下位(右)のものをサーチし,そのビ
120 * ット番号を返す.ビット番号は,最下位ビットを 0 とする.bitmap に 0
121 * を指定してはならない.この関数では,優先度が16段階以下であることを
122 * 仮定し,bitmap の下位16ビットのみをサーチする.
123 * ビットサーチ命令を持つプロセッサでは,ビットサーチ命令を使うように
124 * 書き直した方が効率が良いだろう.このような場合には,cpu_insn.h で
125 * ビットサーチ命令を使った bitmap_search を定義し,CPU_BITMAP_SEARCH
126 * をマクロ定義すればよい.また,ビットサーチ命令のサーチ方向が逆など
127 * の理由で優先度とビットとの対応を変更したい場合には,PRIMAP_BIT を
129 * また,標準ライブラリに ffs があるなら,次のように定義して標準ライ
130 * ブラリを使った方が効率が良い可能性もある.
131 * #define bitmap_search(bitmap) (ffs(bitmap) - 1)
134 #define PRIMAP_BIT(pri) (1u << (pri))
135 #endif /* PRIMAP_BIT */
137 #ifndef CPU_BITMAP_SEARCH
140 bitmap_search(UINT bitmap)
142 static const unsigned char search_table[] = { 0, 1, 0, 2, 0, 1, 0,
143 3, 0, 1, 0, 2, 0, 1, 0 };
146 assert((bitmap & 0xffff) != 0);
147 if ((bitmap & 0x00ff) == 0) {
151 if ((bitmap & 0x0f) == 0) {
155 return(n + search_table[(bitmap & 0x0f) - 1]);
158 #endif /* CPU_BITMAP_SEARCH */
170 schedpri = bitmap_search(ready_primap);
171 return((TCB *)(ready_queue[schedpri].next));
174 #endif /* __tsksched */
179 * 最高優先順位のタスクを更新するのは,実行できるタスクがなかった場合
180 * と,tcb の優先度が最高優先順位のタスクの優先度よりも高い場合である.
185 make_runnable(TCB *tcb)
187 UINT pri = tcb->priority;
189 tcb->tstat = TS_RUNNABLE;
191 queue_insert_prev(&(ready_queue[pri]), &(tcb->task_queue));
192 ready_primap |= PRIMAP_BIT(pri);
194 if (schedtsk == (TCB *) NULL || pri < schedtsk->priority) {
201 #endif /* __tskrun */
206 * 最高優先順位のタスクを更新するのは,tcb が最高優先順位のタスクであっ
207 * た場合である.tcb と同じ優先度のタスクが他にある場合は,tcb の次の
208 * タスクが最高優先順位になる.そうでない場合は,レディキューをサーチ
214 make_non_runnable(TCB *tcb)
216 UINT pri = tcb->priority;
217 QUEUE *queue = &(ready_queue[pri]);
219 queue_delete(&(tcb->task_queue));
220 if (queue_empty(queue)) {
221 ready_primap &= ~PRIMAP_BIT(pri);
222 if (schedtsk == tcb) {
223 schedtsk = (ready_primap == 0) ? (TCB * ) NULL
229 if (schedtsk == tcb) {
230 schedtsk = (TCB *)(queue->next);
237 #endif /* __tsknrun */
245 make_dormant(TCB *tcb)
247 tcb->priority = tcb->tinib->ipriority;
248 tcb->tstat = TS_DORMANT;
256 #endif /* __tskdmt */
264 make_active(TCB *tcb)
266 activate_context(tcb);
267 return(make_runnable(tcb));
270 #endif /* __tskact */
280 make_non_runnable(runtsk);
281 make_dormant(runtsk);
282 if (runtsk->actcnt) {
283 runtsk->actcnt = FALSE;
289 #endif /* __tskext */
294 * 最高優先順位のタスクを更新するのは,(1) tcb が最高優先順位のタスク
295 * であって,その優先度を下げた場合,(2) tcb が最高優先順位のタスクで
296 * はなく,変更後の優先度が最高優先順位のタスクの優先度よりも高い場合
297 * である.(1) の場合には,レディキューをサーチする必要がある.
302 change_priority(TCB *tcb, UINT newpri)
304 UINT oldpri = tcb->priority;
306 tcb->priority = newpri;
307 queue_delete(&(tcb->task_queue));
308 if (queue_empty(&(ready_queue[oldpri]))) {
309 ready_primap &= ~PRIMAP_BIT(oldpri);
311 queue_insert_prev(&(ready_queue[newpri]), &(tcb->task_queue));
312 ready_primap |= PRIMAP_BIT(newpri);
314 if (schedtsk == tcb) {
315 if (newpri >= oldpri) {
316 schedtsk = search_schedtsk();
317 return(schedtsk != tcb && enadsp);
321 if (newpri < schedtsk->priority) {
329 #endif /* __tskpri */
334 * 最高優先順位のタスクを更新するのは,最高優先順位のタスクがタスクキ
340 rotate_ready_queue(UINT pri)
342 QUEUE *queue = &(ready_queue[pri]);
345 if (!(queue_empty(queue)) && queue->next->next != queue) {
346 entry = queue_delete_next(queue);
347 queue_insert_prev(queue, entry);
348 if (schedtsk == (TCB *) entry) {
349 schedtsk = (TCB *)(queue->next);
356 #endif /* __tskrot */
359 * 引数まで定義したタスク例外処理ルーチンの型
361 typedef void (*TEXRTN)(TEXPTN texptn, VP_INT exinf);
374 texptn = runtsk->texptn;
375 runtsk->enatex = FALSE;
378 LOG_TEX_ENTER(texptn);
379 (*((TEXRTN)(runtsk->tinib->texrtn)))(texptn,
380 runtsk->tinib->exinf);
381 LOG_TEX_LEAVE(texptn);
382 if (!t_sense_lock()) {
385 } while (runtsk->texptn != 0);
386 runtsk->enatex = TRUE;
397 if (runtsk->enatex && runtsk->texptn != 0) {
402 #endif /* OMIT_CALLTEX */
403 #endif /* __tsktex */