📄 task.c
字号:
/* * TOPPERS/JSP Kernel * Toyohashi Open Platform for Embedded Real-Time Systems/ * Just Standard Profile Kernel * * Copyright (C) 2000,2001 by Embedded and Real-Time Systems Laboratory * Toyohashi Univ. of Technology, JAPAN * * 惧淡螟侯涪荚は·Free Software Foundation によって给山されている * GNU General Public License の Version 2 に淡揭されている掘凤か·笆 * 布の(1)×(4)の掘凤を塔たす眷圭に嘎り·塑ソフトウェア∈塑ソフトウェ * アを猖恃したものを崔むˉ笆布票じ∷を蝗脱ˇ剩澜ˇ猖恃ˇ浩芹邵∈笆布· * 网脱と钙ぶ∷することを痰浸で钓满するˉ * (1) 塑ソフトウェアをソ〖スコ〖ドの妨で网脱する眷圭には·惧淡の螟侯 * 涪山绩·この网脱掘凤および布淡の痰瘦沮惮年が·そのままの妨でソ〖 * スコ〖ド面に崔まれていることˉ * (2) 塑ソフトウェアを浩网脱材墙なバイナリコ〖ド∈リロケ〖タブルオブ * ジェクトファイルやライブラリなど∷の妨で网脱する眷圭には·网脱 * に燃うドキュメント∈网脱荚マニュアルなど∷に·惧淡の螟侯涪山绩· * この网脱掘凤および布淡の痰瘦沮惮年を非很することˉ * (3) 塑ソフトウェアを浩网脱稍材墙なバイナリコ〖ドの妨または怠达に寥 * み哈んだ妨で网脱する眷圭には·肌のいずれかの掘凤を塔たすことˉ * (a) 网脱に燃うドキュメント∈网脱荚マニュアルなど∷に·惧淡の螟侯 * 涪山绩·この网脱掘凤および布淡の痰瘦沮惮年を非很することˉ * (b) 网脱の妨轮を·侍に年める数恕によって·惧淡螟侯涪荚に鼠桂する * ことˉ * (4) 塑ソフトウェアの网脱により木儡弄または粗儡弄に栏じるいかなる禄 * 巢からも·惧淡螟侯涪荚を倘勒することˉ * * 塑ソフトウェアは·痰瘦沮で捏丁されているものであるˉ惧淡螟侯涪荚は· * 塑ソフトウェアに簇して·その努脱材墙拉も崔めて·いかなる瘦沮も乖わ * ないˉまた·塑ソフトウェアの网脱により木儡弄または粗儡弄に栏じたい * かなる禄巢に簇しても·その勒扦を砷わないˉ * * @(#) $Id: task.c,v 1.6 2002/03/26 08:19:38 hiro Exp $ *//* * タスク瓷妄モジュ〖ル */#include "jsp_kernel.h"#include "task.h"#include "cpu_context.h"/* * 悸乖觉轮のタスク */TCB *runtsk;/* * 呵光庭黎界疤のタスク */TCB *schedtsk;/* * タスクディスパッチ】タスク毋嘲借妄ル〖チン弹瓢妥滇フラグ */BOOL reqflg;/* * タスクディスパッチ钓材觉轮 */BOOL enadsp;/* * レディキュ〖 * * レディキュ〖は·悸乖できる觉轮のタスクを瓷妄するためのキュ〖で·庭 * 黎刨ごとのタスクキュ〖で菇喇されているˉタスクのTCBは·澈碰する庭 * 黎刨のキュ〖に判峡されるˉ */static QUEUE ready_queue[TNUM_TPRI];/* * レディキュ〖サ〖チのためのビットマップ * * レディキュ〖のサ〖チを跟唯よく乖うために·庭黎刨ごとのタスクキュ〖 * にタスクが掐っているかどうかを绩すビットマップを脱罢しているˉビッ * トマップを蝗うことで·メモリアクセスの搀眶を负らすことができるが· * ビット拎侯炭吾が郊悸していないプロセッサで·庭黎刨の檬超眶が警ない * 眷圭には·ビットマップ拎侯のオ〖バ〖ヘッドのために·嫡に跟唯が皖ち * る材墙拉もあるˉ * ビットマップを UINT で年盗しているが·ビットマップサ〖チ簇眶で庭黎 * 刨が16檬超笆布であることを簿年してしているˉ */static UINT ready_primap;/* * タスク瓷妄モジュ〖ルの介袋步 */voidtask_initialize(){ INT i; TCB *tcb; runtsk = schedtsk = NULL; reqflg = FALSE; enadsp = TRUE; for (i = 0; i < TNUM_TPRI; i++) { queue_initialize(&(ready_queue[i])); } ready_primap = 0; for (tcb = tcb_table, i = 0; i < tmax_tskid; tcb++, i++) { tcb->tinib = &(tinib_table[i]); tcb->actcnt = FALSE; make_dormant(tcb); if ((tcb->tinib->tskatr & TA_ACT) != 0) { make_active(tcb); } }}/* * ビットマップサ〖チ簇眶 * * bitmap 柒の 1 のビットの柒·呵も布疤∈宝∷のものをサ〖チし·そのビ * ット戎规を手すˉビット戎规は·呵布疤ビットを 0 とするˉbitmap に 0 * を回年してはならないˉこの簇眶では·庭黎刨が16檬超笆布であることを * 簿年し·bitmapの布疤 16ビットのみをサ〖チするˉ * ビットサ〖チ炭吾を积つCPUでは·ビットサ〖チ炭吾を蝗うように今き木 * した数が跟唯が紊いだろうˉこのような眷圭には·cpu_insn.h でビット * サ〖チ炭吾を蝗った bitmap_search を年盗し·CPU_BITMAP_SEARCH をマ * クロ年盗すればよいˉまた·ビットサ〖チ炭吾のサ〖チ数羹が嫡などの妄 * 统で庭黎刨とビットとの滦炳を恃构したい眷圭には·PRIMAP_BIT をマク * ロ年盗すればよいˉ * また·筛洁ライブラリに ffs があるなら·肌のように年盗して筛洁ライ * ブラリを蝗った数が跟唯が紊い材墙拉もあるˉ * #define bitmap_search(bitmap) (ffs(bitmap) - 1) */#ifndef PRIMAP_BIT#define PRIMAP_BIT(pri) (1 << (pri))#endif /* PRIMAP_BIT */#ifndef CPU_BITMAP_SEARCHInline UINTbitmap_search(UINT bitmap){ static const VB search_table[] = { 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 }; INT n = 0; assert((bitmap & 0xffff) != 0); if ((bitmap & 0x00ff) == 0) { bitmap >>= 8; n += 8; } if ((bitmap & 0x0f) == 0) { bitmap >>= 4; n += 4; } return(n + search_table[(bitmap & 0x0f) - 1]);}#endif /* CPU_BITMAP_SEARCH *//* * 呵光庭黎界疤タスクのサ〖チ * * レディキュ〖面の呵光庭黎界疤のタスクをサ〖チし·そのTCBへのポインタ * を手すˉレディキュ〖が鄂の眷圭には·この簇眶を钙び叫してはならないˉ */static TCB *search_schedtsk(){ UINT schedpri; schedpri = bitmap_search(ready_primap); return((TCB *)(ready_queue[schedpri].next));}/* * 悸乖できる觉轮への败乖 * * 呵光庭黎界疤のタスクを构糠するのは·悸乖できるタスクがなかった眷圭 * と·tcb の庭黎刨が呵光庭黎界疤のタスクの庭黎刨よりも光い眷圭であるˉ */BOOLmake_runnable(TCB *tcb){ UINT pri = tcb->priority; tcb->tstat = TS_RUNNABLE; queue_insert_prev(&(ready_queue[pri]), &(tcb->task_queue)); ready_primap |= PRIMAP_BIT(pri); if (schedtsk == (TCB *) NULL || pri < schedtsk->priority) { schedtsk = tcb; return(enadsp); } return(FALSE);}/* * 悸乖できる觉轮から戮の觉轮への败乖 * * 呵光庭黎界疤のタスクを构糠するのは·tcb が呵光庭黎界疤のタスクであっ * た眷圭であるˉtcb と票じ庭黎刨のタスクが戮にある眷圭は·tcb の肌の * タスクが呵光庭黎界疤になるˉそうでない眷圭は·レディキュ〖をサ〖チ * する涩妥があるˉ */BOOLmake_non_runnable(TCB *tcb){ UINT pri = tcb->priority; QUEUE *queue = &(ready_queue[pri]); queue_delete(&(tcb->task_queue)); if (queue_empty(queue)) { ready_primap &= ~PRIMAP_BIT(pri); if (schedtsk == tcb) { schedtsk = (ready_primap == 0) ? (TCB * ) NULL : search_schedtsk(); return(enadsp); } } else { if (schedtsk == tcb) { schedtsk = (TCB *)(queue->next); return(enadsp); } } return(FALSE);}/* * 蒂贿觉轮への败乖 */voidmake_dormant(TCB *tcb){ tcb->priority = tcb->tinib->ipriority; tcb->tstat = TS_DORMANT; tcb->wupcnt = FALSE; tcb->enatex = FALSE; tcb->texptn = 0; create_context(tcb);}/* * 蒂贿觉轮から悸乖できる觉轮への败乖 */BOOLmake_active(TCB *tcb){ activate_context(tcb); return(make_runnable(tcb));}/* * 悸乖觉轮のタスクの姜位 */voidexit_task(){ make_non_runnable(runtsk); make_dormant(runtsk); if (runtsk->actcnt) { runtsk->actcnt = FALSE; make_active(runtsk); } exit_and_dispatch();}/* * レディキュ〖面のタスクの庭黎刨の恃构 * * 呵光庭黎界疤のタスクを构糠するのは·(1) tcb が呵光庭黎界疤のタスク * であって·その庭黎刨を布げた眷圭·(2) tcb が呵光庭黎界疤のタスクで * はなく·恃构稿の庭黎刨が呵光庭黎界疤のタスクの庭黎刨よりも光い眷圭 * であるˉ(1) の眷圭には·レディキュ〖をサ〖チする涩妥があるˉ */BOOLchange_priority(TCB *tcb, UINT newpri){ UINT oldpri = tcb->priority; tcb->priority = newpri; queue_delete(&(tcb->task_queue)); if (queue_empty(&(ready_queue[oldpri]))) { ready_primap &= ~PRIMAP_BIT(oldpri); } queue_insert_prev(&(ready_queue[newpri]), &(tcb->task_queue)); ready_primap |= PRIMAP_BIT(newpri); if (schedtsk == tcb) { if (newpri >= oldpri) { schedtsk = search_schedtsk(); return(schedtsk != tcb && enadsp); } } else { if (newpri < schedtsk->priority) { schedtsk = tcb; return(enadsp); } } return(FALSE);}/* * レディキュ〖の搀啪 * * 呵光庭黎界疤のタスクを构糠するのは·呵光庭黎界疤のタスクがタスクキ * ュ〖の琐萨に败瓢した眷圭であるˉ */BOOLrotate_ready_queue(UINT pri){ QUEUE *queue = &(ready_queue[pri]); QUEUE *entry; if (!(queue_empty(queue)) && queue->next->next != queue) { entry = queue_delete_next(queue); queue_insert_prev(queue, entry); if (schedtsk == (TCB *) entry) { schedtsk = (TCB *)(queue->next); return(enadsp); } } return(FALSE);}/* * タスク毋嘲借妄ル〖チンの钙叫し */voidcall_texrtn(){ TEXPTN texptn; do { texptn = runtsk->texptn; runtsk->enatex = FALSE; runtsk->texptn = 0; t_unlock_cpu(); (*runtsk->tinib->texrtn)(texptn, runtsk->tinib->exinf); if (!t_sense_lock()) { t_lock_cpu(); } } while (runtsk->texptn != 0); runtsk->enatex = TRUE;}/* * タスク毋嘲借妄ル〖チンの弹瓢 */#ifndef OMIT_CALLTEXvoidcalltex(){ if (runtsk->enatex && runtsk->texptn != 0) { call_texrtn(); }}#endif /* OMIT_CALLTEX */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -