source: anotherchoice/tags/jsp-1.4.4-full-UTF8/kernel/task.c@ 26

Last change on this file since 26 was 26, checked in by ykominami, 10 years ago

initial

File size: 10.3 KB
Line 
1/*
2 * TOPPERS/JSP Kernel
3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Just 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,2006 by Embedded and Real-Time Systems Laboratory
9 * Graduate School of Information Science, Nagoya Univ., JAPAN
10 *
11 * 上記著作権者
12は,以下の (1)〜(4) の条件か,Free Software Foundation
13 * によってå…
14¬è¡¨ã•ã‚Œã¦ã„ã‚‹ GNU General Public License の Version 2 に記
15 * 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
16 * を改変したものを含む.以下同じ)を使用・複製・改変・再é…
17å¸ƒï¼ˆä»¥ä¸‹ï¼Œ
18 * 利用と呼ぶ)することを無償で許諾する.
19 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
20 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
21 * スコード中に含まれていること.
22 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
23 * 用できる形で再é…
24å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
25å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
26 * 者
27マニュアルなど)に,上記の著作権表示,この利用条件および下記
28 * の無保証規定を掲載すること.
29 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
30 * 用できない形で再é…
31å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
32 * と.
33 * (a) 再é…
34å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
35マニュアルなど)に,上記の著
36 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
37 * (b) 再é…
38å¸ƒã®å½¢æ…
39‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
40 * 報告すること.
41 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
42 * 害からも,上記著作権者
43およびTOPPERSプロジェクトをå…
44è²¬ã™ã‚‹ã“と.
45 *
46 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者
47お
48 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
49 * 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
50 * 接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
51 *
52 * @(#) $Id: task.c,v 1.12 2006/02/12 05:29:32 hiro Exp $
53 */
54
55/*
56 * タスク管理モジュール
57 */
58
59#include "jsp_kernel.h"
60#include "task.h"
61#include <cpu_context.h>
62
63#ifdef __tskini
64
65/*
66 * 実行状æ…
67‹ã®ã‚¿ã‚¹ã‚¯
68 */
69TCB *runtsk;
70
71/*
72 * 最高優å…
73ˆé †ä½ã®ã‚¿ã‚¹ã‚¯
74 */
75TCB *schedtsk;
76
77/*
78 * タスクディスパッチ/タスク例外処理ルーチン起動要求フラグ
79 */
80BOOL reqflg;
81
82/*
83 * タスクディスパッチ許可状æ…
84‹
85 */
86BOOL enadsp;
87
88/*
89 * レディキュー
90 */
91QUEUE ready_queue[TNUM_TPRI];
92
93/*
94 * レディキューサーチのためのビットマップ
95 *
96 * ビットマップを UINT で定義しているが,ビットマップサーチ関数で優å…
97ˆ
98 * 度が16段階以下であることを仮定している.
99 */
100UINT ready_primap;
101
102/*
103 * タスク管理モジュールの初期化
104 */
105void
106task_initialize()
107{
108 UINT i, j;
109 TCB *tcb;
110
111 runtsk = schedtsk = NULL;
112 reqflg = FALSE;
113 enadsp = TRUE;
114
115 for (i = 0; i < TNUM_TPRI; i++) {
116 queue_initialize(&(ready_queue[i]));
117 }
118 ready_primap = 0;
119
120 for (i = 0; i < TNUM_TSK; i++) {
121 j = INDEX_TSK(torder_table[i]);
122 tcb = &(tcb_table[j]);
123 tcb->tinib = &(tinib_table[j]);
124 tcb->actcnt = FALSE;
125 make_dormant(tcb);
126 if ((tcb->tinib->tskatr & TA_ACT) != 0) {
127 make_active(tcb);
128 }
129 }
130}
131
132#endif /* __tskini */
133
134/*
135 * ビットマップサーチ関数
136 *
137 * bitmap 内
138の 1 のビットの内
139,最も下位(右)のものをサーチし,そのビ
140 * ット番号を返す.ビット番号は,最下位ビットを 0 とする.bitmap に 0
141 * を指定してはならない.この関数では,優å…
142ˆåº¦ãŒ16段階以下であることを
143 * 仮定し,bitmap の下位16ビットのみをサーチする.
144 * ビットサーチ命令を持つプロセッサでは,ビットサーチ命令を使うように
145 * 書き直した方が効率が良いだろう.このような場合には,cpu_insn.h で
146 * ビットサーチ命令を使った bitmap_search を定義し,CPU_BITMAP_SEARCH
147 * をマクロ定義すればよい.また,ビットサーチ命令のサーチ方向が逆など
148 * の理由で優å…
149ˆåº¦ã¨ãƒ“ットとの対応を変更したい場合には,PRIMAP_BIT を
150 * マクロ定義すればよい.
151 * また,標準ライブラリに ffs があるなら,次のように定義して標準ライ
152 * ブラリを使った方が効率が良い可能性もある.
153 * #define bitmap_search(bitmap) (ffs(bitmap) - 1)
154 */
155#ifndef PRIMAP_BIT
156#define PRIMAP_BIT(pri) (1u << (pri))
157#endif /* PRIMAP_BIT */
158
159#ifndef CPU_BITMAP_SEARCH
160
161Inline UINT
162bitmap_search(UINT bitmap)
163{
164 static const unsigned char search_table[] = { 0, 1, 0, 2, 0, 1, 0,
165 3, 0, 1, 0, 2, 0, 1, 0 };
166 UINT n = 0;
167
168 assert((bitmap & 0xffff) != 0);
169 if ((bitmap & 0x00ff) == 0) {
170 bitmap >>= 8;
171 n += 8;
172 }
173 if ((bitmap & 0x0f) == 0) {
174 bitmap >>= 4;
175 n += 4;
176 }
177 return(n + search_table[(bitmap & 0x0f) - 1]);
178}
179
180#endif /* CPU_BITMAP_SEARCH */
181
182/*
183 * 最高優å…
184ˆé †ä½ã‚¿ã‚¹ã‚¯ã®ã‚µãƒ¼ãƒ
185 */
186#ifdef __tsksched
187
188TCB *
189search_schedtsk()
190{
191 UINT schedpri;
192
193 schedpri = bitmap_search(ready_primap);
194 return((TCB *)(ready_queue[schedpri].next));
195}
196
197#endif /* __tsksched */
198
199/*
200 * 実行できる状æ…
201‹ã¸ã®ç§»è¡Œ
202 *
203 * 最高優å…
204ˆé †ä½ã®ã‚¿ã‚¹ã‚¯ã‚’更新するのは,実行できるタスクがなかった場合
205 * と,tcb の優å…
206ˆåº¦ãŒæœ€é«˜å„ªå…
207ˆé †ä½ã®ã‚¿ã‚¹ã‚¯ã®å„ªå…
208ˆåº¦ã‚ˆã‚Šã‚‚高い場合である.
209 */
210#ifdef __tskrun
211
212BOOL
213make_runnable(TCB *tcb)
214{
215 UINT pri = tcb->priority;
216
217 tcb->tstat = TS_RUNNABLE;
218 LOG_TSKSTAT(tcb);
219 queue_insert_prev(&(ready_queue[pri]), &(tcb->task_queue));
220 ready_primap |= PRIMAP_BIT(pri);
221
222 if (schedtsk == (TCB *) NULL || pri < schedtsk->priority) {
223 schedtsk = tcb;
224 return(enadsp);
225 }
226 return(FALSE);
227}
228
229#endif /* __tskrun */
230
231/*
232 * 実行できる状æ…
233‹ã‹ã‚‰ä»–の状æ…
234‹ã¸ã®ç§»è¡Œ
235 *
236 * 最高優å…
237ˆé †ä½ã®ã‚¿ã‚¹ã‚¯ã‚’更新するのは,tcb が最高優å…
238ˆé †ä½ã®ã‚¿ã‚¹ã‚¯ã§ã‚っ
239 * た場合である.tcb と同じ優å…
240ˆåº¦ã®ã‚¿ã‚¹ã‚¯ãŒä»–にある場合は,tcb の次の
241 * タスクが最高優å…
242ˆé †ä½ã«ãªã‚‹ï¼Žãã†ã§ãªã„場合は,レディキューをサーチ
243 * する必
244要がある.
245 */
246#ifdef __tsknrun
247
248BOOL
249make_non_runnable(TCB *tcb)
250{
251 UINT pri = tcb->priority;
252 QUEUE *queue = &(ready_queue[pri]);
253
254 queue_delete(&(tcb->task_queue));
255 if (queue_empty(queue)) {
256 ready_primap &= ~PRIMAP_BIT(pri);
257 if (schedtsk == tcb) {
258 schedtsk = (ready_primap == 0) ? (TCB * ) NULL
259 : search_schedtsk();
260 return(enadsp);
261 }
262 }
263 else {
264 if (schedtsk == tcb) {
265 schedtsk = (TCB *)(queue->next);
266 return(enadsp);
267 }
268 }
269 return(FALSE);
270}
271
272#endif /* __tsknrun */
273
274/*
275 * 休止状æ…
276‹ã¸ã®ç§»è¡Œ
277 */
278#ifdef __tskdmt
279
280void
281make_dormant(TCB *tcb)
282{
283 tcb->priority = tcb->tinib->ipriority;
284 tcb->tstat = TS_DORMANT;
285 tcb->wupcnt = FALSE;
286 tcb->enatex = FALSE;
287 tcb->texptn = 0;
288 create_context(tcb);
289 LOG_TSKSTAT(tcb);
290}
291
292#endif /* __tskdmt */
293
294/*
295 * 休止状æ…
296‹ã‹ã‚‰å®Ÿè¡Œã§ãã‚‹çŠ¶æ…
297‹ã¸ã®ç§»è¡Œ
298 */
299#ifdef __tskact
300
301BOOL
302make_active(TCB *tcb)
303{
304 activate_context(tcb);
305 return(make_runnable(tcb));
306}
307
308#endif /* __tskact */
309
310/*
311 * 実行状æ…
312‹ã®ã‚¿ã‚¹ã‚¯ã®çµ‚了
313 */
314#ifdef __tskext
315
316void
317exit_task()
318{
319 make_non_runnable(runtsk);
320 make_dormant(runtsk);
321 if (runtsk->actcnt) {
322 runtsk->actcnt = FALSE;
323 make_active(runtsk);
324 }
325 exit_and_dispatch();
326}
327
328#endif /* __tskext */
329
330/*
331 * レディキュー中のタスクの優å…
332ˆåº¦ã®å¤‰æ›´
333 *
334 * 最高優å…
335ˆé †ä½ã®ã‚¿ã‚¹ã‚¯ã‚’更新するのは,(1) tcb が最高優å…
336ˆé †ä½ã®ã‚¿ã‚¹ã‚¯
337 * であって,その優å…
338ˆåº¦ã‚’下げた場合,(2) tcb が最高優å…
339ˆé †ä½ã®ã‚¿ã‚¹ã‚¯ã§
340 * はなく,変更後の優å…
341ˆåº¦ãŒæœ€é«˜å„ªå…
342ˆé †ä½ã®ã‚¿ã‚¹ã‚¯ã®å„ªå…
343ˆåº¦ã‚ˆã‚Šã‚‚高い場合
344 * である.(1) の場合には,レディキューをサーチする必
345要がある.
346 */
347#ifdef __tskpri
348
349BOOL
350change_priority(TCB *tcb, UINT newpri)
351{
352 UINT oldpri = tcb->priority;
353
354 tcb->priority = newpri;
355 queue_delete(&(tcb->task_queue));
356 if (queue_empty(&(ready_queue[oldpri]))) {
357 ready_primap &= ~PRIMAP_BIT(oldpri);
358 }
359 queue_insert_prev(&(ready_queue[newpri]), &(tcb->task_queue));
360 ready_primap |= PRIMAP_BIT(newpri);
361
362 if (schedtsk == tcb) {
363 if (newpri >= oldpri) {
364 schedtsk = search_schedtsk();
365 return(schedtsk != tcb && enadsp);
366 }
367 }
368 else {
369 if (newpri < schedtsk->priority) {
370 schedtsk = tcb;
371 return(enadsp);
372 }
373 }
374 return(FALSE);
375}
376
377#endif /* __tskpri */
378
379/*
380 * レディキューの回転
381 *
382 * 最高優å…
383ˆé †ä½ã®ã‚¿ã‚¹ã‚¯ã‚’更新するのは,最高優å…
384ˆé †ä½ã®ã‚¿ã‚¹ã‚¯ãŒã‚¿ã‚¹ã‚¯ã‚­
385 * ューの末尾に移動した場合である.
386 */
387#ifdef __tskrot
388
389BOOL
390rotate_ready_queue(UINT pri)
391{
392 QUEUE *queue = &(ready_queue[pri]);
393 QUEUE *entry;
394
395 if (!(queue_empty(queue)) && queue->next->next != queue) {
396 entry = queue_delete_next(queue);
397 queue_insert_prev(queue, entry);
398 if (schedtsk == (TCB *) entry) {
399 schedtsk = (TCB *)(queue->next);
400 return(enadsp);
401 }
402 }
403 return(FALSE);
404}
405
406#endif /* __tskrot */
407
408/*
409 * 引数まで定義したタスク例外処理ルーチンの型
410 */
411typedef void (*TEXRTN)(TEXPTN texptn, VP_INT exinf);
412
413/*
414 * タスク例外処理ルーチンの呼出し
415 */
416#ifdef __tsktex
417
418void
419call_texrtn()
420{
421 TEXPTN texptn;
422
423 do {
424 texptn = runtsk->texptn;
425 runtsk->enatex = FALSE;
426 runtsk->texptn = 0;
427 t_unlock_cpu();
428 LOG_TEX_ENTER(texptn);
429 (*((TEXRTN)(runtsk->tinib->texrtn)))(texptn,
430 runtsk->tinib->exinf);
431 LOG_TEX_LEAVE(texptn);
432 if (!t_sense_lock()) {
433 t_lock_cpu();
434 }
435 } while (runtsk->texptn != 0);
436 runtsk->enatex = TRUE;
437}
438
439/*
440 * タスク例外処理ルーチンの起動
441 */
442#ifndef OMIT_CALLTEX
443
444void
445calltex()
446{
447 if (runtsk->enatex && runtsk->texptn != 0) {
448 call_texrtn();
449 }
450}
451
452#endif /* OMIT_CALLTEX */
453#endif /* __tsktex */
Note: See TracBrowser for help on using the repository browser.