|
|
task.c説明を見る。00001 /* 00002 * TOPPERS/FDMP Kernel 00003 * Toyohashi Open Platform for Embedded Real-Time Systems/ 00004 * Function Distributed Multiprocessor Kernel 00005 * 00006 * Copyright (C) 2000-2004 by Embedded and Real-Time Systems Laboratory 00007 * Toyohashi Univ. of Technology, JAPAN 00008 * Copyright (C) 2005-2006 by Embedded and Real-Time Systems Laboratory 00009 * Graduate School of Information Science, Nagoya Univ., JAPAN 00010 * 00011 * 上記著作権者は,以下の (1)〜(4) の条件か,Free Software Foundation 00012 * によって公表されている GNU General Public License の Version 2 に記 00013 * 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア 00014 * を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下, 00015 * 利用と呼ぶ)することを無償で許諾する. 00016 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作 00017 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー 00018 * スコード中に含まれていること. 00019 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使 00020 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用 00021 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記 00022 * の無保証規定を掲載すること. 00023 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使 00024 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ 00025 * と. 00026 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著 00027 * 作権表示,この利用条件および下記の無保証規定を掲載すること. 00028 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに 00029 * 報告すること. 00030 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損 00031 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること. 00032 * 00033 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お 00034 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も 00035 * 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直 00036 * 接的または間接的に生じたいかなる損害に関しても,その責任を負わない. 00037 * 00038 * @(#) $Id: task.c,v 1.3 2006/03/14 04:37:54 honda Exp $ 00039 */ 00040 00045 #include "fdmp_kernel.h" 00046 #include "task.h" 00047 #include "cpu_context.h" 00048 00049 #ifdef __tskini 00050 00054 TCB *runtsk; 00055 00059 TCB *schedtsk; 00060 00064 BOOL reqflg; 00065 00069 BOOL enadsp; 00070 00074 QUEUE ready_queue[TNUM_TPRI]; 00075 00082 UINT ready_primap; 00083 00084 00089 void 00090 task_initialize() 00091 { 00092 UINT i; 00093 TCB *tcb; 00094 00095 runtsk = schedtsk = NULL; 00096 runccb = my_local_ccb; /* 現時点では意味無し */ 00097 reqflg = FALSE; 00098 enadsp = TRUE; 00099 00100 for (i = 0; i < TNUM_TPRI; i++) { 00101 queue_initialize(&(ready_queue[i])); 00102 } 00103 ready_primap = 0; 00104 00105 for (i = 0; i < MY_TNUM_TSK; i++) { 00106 tcb = &(tcb_table[i]); 00107 tcb->tinib = &(tinib_table[i]); 00108 tcb->actcnt = FALSE; 00109 00110 tcb->clsid = CLS_MY_LOCAL; 00111 tcb->pend_chgpri = FALSE; 00112 tcb->pend_tertsk = FALSE; 00113 tcb->pend_relwai = FALSE; 00114 tcb->terflg = FALSE; 00115 00116 make_dormant(tcb); 00117 } 00118 00119 my_local_exccb->p_ready_queue = &ready_queue[0]; 00120 my_local_exccb->p_ready_primap = &ready_primap; 00121 my_local_exccb->p_runtsk = &runtsk; 00122 my_local_exccb->p_schedtsk = &schedtsk; 00123 my_local_exccb->p_enadsp = &enadsp; 00124 00125 my_local_exccb->tsk.cb_table = &tcb_table[0]; 00126 my_local_exccb->tsk.max_id = tmax_tskid; 00127 00128 my_local_exccb->p_activate_r = activate_r; 00129 } 00130 00131 #endif /* __tskini */ 00132 00133 00139 #ifdef __tskiniact 00140 00141 void 00142 task_init_activate() 00143 { 00144 UINT i, j; 00145 TCB *tcb; 00146 00147 for (i = 0; i < MY_TNUM_TSK; i++) { 00148 j = INDEX_TSK(torder_table[i]); 00149 tcb = &(tcb_table[j]); 00150 if ((tcb->tinib->tskatr & TA_ACT) != 0) { 00151 make_active(my_local_ccb, tcb); 00152 } 00153 } 00154 } 00155 00156 #endif /* __tskiniact */ 00157 00175 #ifndef PRIMAP_BIT 00176 #define PRIMAP_BIT(pri) (1u << (pri)) 00177 #endif /* PRIMAP_BIT */ 00178 00179 #ifndef CPU_BITMAP_SEARCH 00180 00181 Inline UINT 00182 bitmap_search(UINT bitmap) 00183 { 00184 static const VB search_table[] = { 0, 1, 0, 2, 0, 1, 0, 00185 3, 0, 1, 0, 2, 0, 1, 0 }; 00186 INT n = 0; 00187 00188 assert((bitmap & 0xffff) != 0); 00189 if ((bitmap & 0x00ff) == 0) { 00190 bitmap >>= 8; 00191 n += 8; 00192 } 00193 if ((bitmap & 0x0f) == 0) { 00194 bitmap >>= 4; 00195 n += 4; 00196 } 00197 return(n + search_table[(bitmap & 0x0f) - 1]); 00198 } 00199 00200 #endif /* CPU_BITMAP_SEARCH */ 00201 00202 00206 #ifdef __tsksched 00207 00208 TCB * 00209 search_schedtsk(CCB *ccb) 00210 { 00211 UINT schedpri; 00212 00213 schedpri = bitmap_search(*(ccb->p_ready_primap)); 00214 return((TCB *)(ccb->p_ready_queue[schedpri].next)); 00215 } 00216 00217 #endif /* __tsksched */ 00218 00225 #ifdef __tskrun 00226 00227 BOOL 00228 make_runnable(CCB *ccb, TCB *tcb) 00229 { 00230 UINT pri = tcb->priority; 00231 00232 tcb->tstat = TS_RUNNABLE; 00233 LOG_TSKSTAT(tcb); 00234 queue_insert_prev(&(ccb->p_ready_queue[pri]), &(tcb->task_queue)); 00235 *(ccb->p_ready_primap) |= PRIMAP_BIT(pri); 00236 00237 if (*(ccb->p_schedtsk) == (TCB *) NULL || pri < (*(ccb->p_schedtsk))->priority){ 00238 *(ccb->p_schedtsk) = tcb; 00239 return(*(ccb->p_enadsp)); 00240 } 00241 return(FALSE); 00242 } 00243 00244 #endif /* __tskrun */ 00245 00254 #ifdef __tsknrun 00255 00256 BOOL 00257 make_non_runnable(CCB *ccb, TCB *tcb) 00258 { 00259 UINT pri = tcb->priority; 00260 QUEUE *queue = &(ccb->p_ready_queue[pri]); 00261 00262 queue_delete(&(tcb->task_queue)); 00263 if (queue_empty(queue)) { 00264 *(ccb->p_ready_primap) &= ~PRIMAP_BIT(pri); 00265 if (*(ccb->p_schedtsk) == tcb) { 00266 *(ccb->p_schedtsk) = (*(ccb->p_ready_primap) == 0) ? (TCB * ) NULL 00267 : search_schedtsk(ccb); 00268 return(*(ccb->p_enadsp)); 00269 } 00270 } 00271 else { 00272 if (*(ccb->p_schedtsk) == tcb) { 00273 *(ccb->p_schedtsk) = (TCB *)(queue->next); 00274 return(*(ccb->p_enadsp)); 00275 } 00276 } 00277 return(FALSE); 00278 } 00279 00280 #endif /* __tsknrun */ 00281 00285 #ifdef __tskdmt 00286 00287 void 00288 make_dormant(TCB *tcb) 00289 { 00290 tcb->priority = tcb->tinib->ipriority; 00291 tcb->tstat = TS_DORMANT; 00292 tcb->wupcnt = FALSE; 00293 tcb->enatex = FALSE; 00294 tcb->texptn = 0; 00295 tcb->pend_chgpri = FALSE; 00296 tcb->pend_tertsk = FALSE; 00297 tcb->pend_relwai = FALSE; 00298 LOG_TSKSTAT(tcb); 00299 } 00300 00301 #endif /* __tskdmt */ 00302 00306 #ifdef __tskact 00307 00308 BOOL 00309 make_active(CCB *ccb, TCB *tcb) 00310 { 00311 activate_context(ccb, tcb); 00312 return(make_runnable(ccb,tcb)); 00313 } 00314 00315 #endif /* __tskact */ 00316 00322 #ifdef __tskdisreq 00323 00324 BOOL 00325 dispatch_request(INT prcid) 00326 { 00327 if (prcid != 0 && prcid != PRCID) { 00328 raise_ipi(prcid); 00329 return(FALSE); 00330 } 00331 return(TRUE); 00332 } 00333 00334 #endif /* __tskdisreq */ 00335 00344 #ifdef __tskpri 00345 00346 BOOL 00347 change_priority(CCB *ccb, TCB *tcb, UINT newpri) 00348 { 00349 UINT oldpri = tcb->priority; 00350 00351 tcb->priority = newpri; 00352 queue_delete(&(tcb->task_queue)); 00353 if (queue_empty(&(ccb->p_ready_queue[oldpri]))) { 00354 *(ccb->p_ready_primap) &= ~PRIMAP_BIT(oldpri); 00355 } 00356 queue_insert_prev(&(ccb->p_ready_queue[newpri]), &(tcb->task_queue)); 00357 *(ccb->p_ready_primap) |= PRIMAP_BIT(newpri); 00358 00359 if (*(ccb->p_schedtsk) == tcb) { 00360 if (newpri >= oldpri) { 00361 *(ccb->p_schedtsk) = search_schedtsk(ccb); 00362 return(*(ccb->p_schedtsk) != tcb && *(ccb->p_enadsp)); 00363 } 00364 } 00365 else { 00366 if (newpri < (*ccb->p_schedtsk)->priority) { 00367 *(ccb->p_schedtsk) = tcb; 00368 return(*(ccb->p_enadsp)); 00369 } 00370 } 00371 return(FALSE); 00372 } 00373 00374 #endif /* __tskpri */ 00375 00382 #ifdef __tskrot 00383 00384 BOOL 00385 rotate_ready_queue(CCB *ccb,UINT pri) 00386 { 00387 QUEUE *queue = &(ccb->p_ready_queue[pri]); 00388 QUEUE *entry; 00389 00390 if (!(queue_empty(queue)) && queue->next->next != queue) { 00391 entry = queue_delete_next(queue); 00392 queue_insert_prev(queue, entry); 00393 if (*(ccb->p_schedtsk) == (TCB *) entry) { 00394 *(ccb->p_schedtsk) = (TCB *)(queue->next); 00395 return(*(ccb->p_enadsp)); 00396 } 00397 } 00398 return(FALSE); 00399 } 00400 00401 #endif /* __tskrot */ 00402 00406 typedef void (*TEXRTN)(TEXPTN texptn, VP_INT exinf); 00407 00408 00412 #ifdef __tsktex 00413 00414 void 00415 call_texrtn() 00416 { 00417 TEXPTN texptn; 00418 00419 do { 00420 texptn = runtsk->texptn; 00421 runtsk->enatex = FALSE; 00422 runtsk->texptn = 0; 00423 T_RELEASE_LOCK(runccb->tsk_lock); 00424 00425 LOG_TEX_ENTER(texptn); 00426 ((TEXRTN)(*runtsk->tinib->texrtn))(texptn, 00427 runtsk->tinib->exinf); 00428 /* 00429 * タスク例外処理ルーチンからCPUロック状態で 00430 * 戻ってきたときの対処 00431 */ 00432 if (t_sense_lock()) { 00433 t_unlock_cpu(); 00434 } 00435 LOG_TEX_LEAVE(texptn); 00436 00437 retry: 00438 T_ACQUIRE_LOCK(runccb->tsk_lock); 00439 } while (runtsk->texptn != 0); 00440 runtsk->enatex = TRUE; 00441 } 00442 00443 00448 void 00449 dispatch_call_texrtn() 00450 { 00451 retry: 00452 if (ACQUIRE_LOCK(runccb->tsk_lock)) { 00453 t_unlock_cpu(); 00454 t_lock_cpu(); 00455 goto retry; 00456 } 00457 if (runtsk->enatex && runtsk->texptn != 0) { 00458 call_texrtn(); 00459 } 00460 RELEASE_LOCK(runccb->tsk_lock); 00461 } 00462 00463 /* 00464 * タスク例外処理ルーチンの起動 00465 */ 00466 #ifndef OMIT_CALLTEX 00467 00468 void 00469 calltex() 00470 { 00471 if (runtsk->enatex && runtsk->texptn != 0) { 00472 dispatch_call_texrtn(); 00473 } 00474 } 00475 00476 #endif /* OMIT_CALLTEX */ 00477 #endif /* __tsktex */ Copyright © 2006 by TAKAGI Nobuhisa. このページは Mon Apr 3 23:49:13 2006 に Doxygen によって生成されました。 |