00001 /* 00002 * TOPPERS/ASP Kernel 00003 * Toyohashi Open Platform for Embedded Real-Time Systems/ 00004 * Advanced Standard Profile Kernel 00005 * 00006 * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory 00007 * Toyohashi Univ. of Technology, JAPAN 00008 * Copyright (C) 2005-2008 by Embedded and Real-Time Systems Laboratory 00009 * Graduate School of Information Science, Nagoya Univ., JAPAN 00010 * 00011 * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ 00012 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改 00013 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する. 00014 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作 00015 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー 00016 * スコード中に含まれていること. 00017 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使 00018 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用 00019 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記 00020 * の無保証規定を掲載すること. 00021 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使 00022 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ 00023 * と. 00024 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著 00025 * 作権表示,この利用条件および下記の無保証規定を掲載すること. 00026 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに 00027 * 報告すること. 00028 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損 00029 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること. 00030 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理 00031 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを 00032 * 免責すること. 00033 * 00034 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お 00035 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的 00036 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ 00037 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ 00038 * の責任を負わない. 00039 * 00040 * @(#) $Id: mempfix.c 748 2008-03-07 17:18:06Z hiro $ 00041 */ 00042 00043 /* 00044 * 固定長メモリプール機能 00045 */ 00046 00047 #include "kernel_impl.h" 00048 #include "check.h" 00049 #include "task.h" 00050 #include "wait.h" 00051 #include "mempfix.h" 00052 00053 /* 00054 * トレースログマクロのデフォルト定義 00055 */ 00056 #ifndef LOG_GET_MPF_ENTER 00057 #define LOG_GET_MPF_ENTER(mpfid, p_blk) 00058 #endif /* LOG_GET_MPF_ENTER */ 00059 00060 #ifndef LOG_GET_MPF_LEAVE 00061 #define LOG_GET_MPF_LEAVE(ercd, blk) 00062 #endif /* LOG_GET_MPF_LEAVE */ 00063 00064 #ifndef LOG_PGET_MPF_ENTER 00065 #define LOG_PGET_MPF_ENTER(mpfid, p_blk) 00066 #endif /* LOG_PGET_MPF_ENTER */ 00067 00068 #ifndef LOG_PGET_MPF_LEAVE 00069 #define LOG_PGET_MPF_LEAVE(ercd, blk) 00070 #endif /* LOG_PGET_MPF_LEAVE */ 00071 00072 #ifndef LOG_TGET_MPF_ENTER 00073 #define LOG_TGET_MPF_ENTER(mpfid, p_blk, tmout) 00074 #endif /* LOG_TGET_MPF_ENTER */ 00075 00076 #ifndef LOG_TGET_MPF_LEAVE 00077 #define LOG_TGET_MPF_LEAVE(ercd, blk) 00078 #endif /* LOG_TGET_MPF_LEAVE */ 00079 00080 #ifndef LOG_REL_MPF_ENTER 00081 #define LOG_REL_MPF_ENTER(mpfid, blk) 00082 #endif /* LOG_REL_MPF_ENTER */ 00083 00084 #ifndef LOG_REL_MPF_LEAVE 00085 #define LOG_REL_MPF_LEAVE(ercd) 00086 #endif /* LOG_REL_MPF_LEAVE */ 00087 00088 #ifndef LOG_INI_MPF_ENTER 00089 #define LOG_INI_MPF_ENTER(mpfid) 00090 #endif /* LOG_INI_MPF_ENTER */ 00091 00092 #ifndef LOG_INI_MPF_LEAVE 00093 #define LOG_INI_MPF_LEAVE(ercd) 00094 #endif /* LOG_INI_MPF_LEAVE */ 00095 00096 #ifndef LOG_REF_MPF_ENTER 00097 #define LOG_REF_MPF_ENTER(mpfid, pk_rmpf) 00098 #endif /* LOG_REF_MPF_ENTER */ 00099 00100 #ifndef LOG_REF_MPF_LEAVE 00101 #define LOG_REF_MPF_LEAVE(ercd, pk_rmpf) 00102 #endif /* LOG_REF_MPF_LEAVE */ 00103 00104 /* 00105 * 固定長メモリプールの数 00106 */ 00107 #define tnum_mpf ((uint_t)(tmax_mpfid - TMIN_MPFID + 1)) 00108 00109 /* 00110 * 固定長メモリプールIDから固定長メモリプール管理ブロックを取り出すた 00111 * めのマクロ 00112 */ 00113 #define INDEX_MPF(mpfid) ((uint_t)((mpfid) - TMIN_MPFID)) 00114 #define get_mpfcb(mpfid) (&(mpfcb_table[INDEX_MPF(mpfid)])) 00115 00116 /* 00117 * 特殊なインデックス値の定義 00118 */ 00119 #define INDEX_NULL (~0U) /* 空きブロックリストの最後 */ 00120 #define INDEX_ALLOC (~1U) /* 割当て済みのブロック */ 00121 00122 /* 00123 * 固定長メモリプール機能の初期化 00124 */ 00125 #ifdef TOPPERS_mpfini 00126 00127 void 00128 initialize_mempfix(void) 00129 { 00130 uint_t i; 00131 MPFCB *p_mpfcb; 00132 00133 for (p_mpfcb = mpfcb_table, i = 0; i < tnum_mpf; p_mpfcb++, i++) { 00134 queue_initialize(&(p_mpfcb->wait_queue)); 00135 p_mpfcb->p_mpfinib = &(mpfinib_table[i]); 00136 p_mpfcb->fblkcnt = p_mpfcb->p_mpfinib->blkcnt; 00137 p_mpfcb->unused = 0U; 00138 p_mpfcb->freelist = INDEX_NULL; 00139 } 00140 } 00141 00142 #endif /* TOPPERS_mpfini */ 00143 00144 /* 00145 * 固定長メモリプールからブロックを獲得 00146 */ 00147 #ifdef TOPPERS_mpfget 00148 00149 void 00150 get_mpf_block(MPFCB *p_mpfcb, void **p_blk) 00151 { 00152 uint_t blkidx; 00153 00154 if (p_mpfcb->freelist != INDEX_NULL) { 00155 blkidx = p_mpfcb->freelist; 00156 p_mpfcb->freelist = (p_mpfcb->p_mpfinib->p_mpfmb + blkidx)->next; 00157 } 00158 else { 00159 blkidx = p_mpfcb->unused; 00160 p_mpfcb->unused++; 00161 } 00162 *p_blk = (void *)((char *)(p_mpfcb->p_mpfinib->mpf) 00163 + p_mpfcb->p_mpfinib->blksz * blkidx); 00164 p_mpfcb->fblkcnt--; 00165 (p_mpfcb->p_mpfinib->p_mpfmb + blkidx)->next = INDEX_ALLOC; 00166 } 00167 00168 #endif /* TOPPERS_mpfget */ 00169 00170 /* 00171 * 固定長メモリブロックの獲得 00172 */ 00173 #ifdef TOPPERS_get_mpf 00174 00175 ER 00176 get_mpf(ID mpfid, void **p_blk) 00177 { 00178 MPFCB *p_mpfcb; 00179 WINFO_MPF winfo_mpf; 00180 ER ercd; 00181 00182 LOG_GET_MPF_ENTER(mpfid, p_blk); 00183 CHECK_DISPATCH(); 00184 CHECK_MPFID(mpfid); 00185 p_mpfcb = get_mpfcb(mpfid); 00186 00187 t_lock_cpu(); 00188 if (p_mpfcb->fblkcnt > 0) { 00189 get_mpf_block(p_mpfcb, p_blk); 00190 ercd = E_OK; 00191 } 00192 else { 00193 p_runtsk->tstat = (TS_WAITING | TS_WAIT_MPF); 00194 wobj_make_wait((WOBJCB *) p_mpfcb, (WINFO_WOBJ *) &winfo_mpf); 00195 dispatch(); 00196 ercd = winfo_mpf.winfo.wercd; 00197 if (ercd == E_OK) { 00198 *p_blk = winfo_mpf.blk; 00199 } 00200 } 00201 t_unlock_cpu(); 00202 00203 error_exit: 00204 LOG_GET_MPF_LEAVE(ercd, *p_blk); 00205 return(ercd); 00206 } 00207 00208 #endif /* TOPPERS_get_mpf */ 00209 00210 /* 00211 * 固定長メモリブロックの獲得(ポーリング) 00212 */ 00213 #ifdef TOPPERS_pget_mpf 00214 00215 ER 00216 pget_mpf(ID mpfid, void **p_blk) 00217 { 00218 MPFCB *p_mpfcb; 00219 ER ercd; 00220 00221 LOG_PGET_MPF_ENTER(mpfid, p_blk); 00222 CHECK_TSKCTX_UNL(); 00223 CHECK_MPFID(mpfid); 00224 p_mpfcb = get_mpfcb(mpfid); 00225 00226 t_lock_cpu(); 00227 if (p_mpfcb->fblkcnt > 0) { 00228 get_mpf_block(p_mpfcb, p_blk); 00229 ercd = E_OK; 00230 } 00231 else { 00232 ercd = E_TMOUT; 00233 } 00234 t_unlock_cpu(); 00235 00236 error_exit: 00237 LOG_PGET_MPF_LEAVE(ercd, *p_blk); 00238 return(ercd); 00239 } 00240 00241 #endif /* TOPPERS_pget_mpf */ 00242 00243 /* 00244 * 固定長メモリブロックの獲得(タイムアウトあり) 00245 */ 00246 #ifdef TOPPERS_tget_mpf 00247 00248 ER 00249 tget_mpf(ID mpfid, void **p_blk, TMO tmout) 00250 { 00251 MPFCB *p_mpfcb; 00252 WINFO_MPF winfo_mpf; 00253 TMEVTB tmevtb; 00254 ER ercd; 00255 00256 LOG_TGET_MPF_ENTER(mpfid, p_blk, tmout); 00257 CHECK_DISPATCH(); 00258 CHECK_MPFID(mpfid); 00259 CHECK_TMOUT(tmout); 00260 p_mpfcb = get_mpfcb(mpfid); 00261 00262 t_lock_cpu(); 00263 if (p_mpfcb->fblkcnt > 0) { 00264 get_mpf_block(p_mpfcb, p_blk); 00265 ercd = E_OK; 00266 } 00267 else if (tmout == TMO_POL) { 00268 ercd = E_TMOUT; 00269 } 00270 else { 00271 p_runtsk->tstat = (TS_WAITING | TS_WAIT_MPF); 00272 wobj_make_wait_tmout((WOBJCB *) p_mpfcb, (WINFO_WOBJ *) &winfo_mpf, 00273 &tmevtb, tmout); 00274 dispatch(); 00275 ercd = winfo_mpf.winfo.wercd; 00276 if (ercd == E_OK) { 00277 *p_blk = winfo_mpf.blk; 00278 } 00279 } 00280 t_unlock_cpu(); 00281 00282 error_exit: 00283 LOG_TGET_MPF_LEAVE(ercd, *p_blk); 00284 return(ercd); 00285 } 00286 00287 #endif /* TOPPERS_tget_mpf */ 00288 00289 /* 00290 * 固定長メモリブロックの返却 00291 */ 00292 #ifdef TOPPERS_rel_mpf 00293 00294 ER 00295 rel_mpf(ID mpfid, void *blk) 00296 { 00297 MPFCB *p_mpfcb; 00298 SIZE blkoffset; 00299 uint_t blkidx; 00300 TCB *p_tcb; 00301 ER ercd; 00302 00303 LOG_REL_MPF_ENTER(mpfid, blk); 00304 CHECK_TSKCTX_UNL(); 00305 CHECK_MPFID(mpfid); 00306 p_mpfcb = get_mpfcb(mpfid); 00307 CHECK_PAR(p_mpfcb->p_mpfinib->mpf <= blk); 00308 blkoffset = ((char *) blk) - (char *)(p_mpfcb->p_mpfinib->mpf); 00309 CHECK_PAR(blkoffset % p_mpfcb->p_mpfinib->blksz == 0U); 00310 CHECK_PAR(blkoffset / p_mpfcb->p_mpfinib->blksz < p_mpfcb->unused); 00311 blkidx = (uint_t)(blkoffset / p_mpfcb->p_mpfinib->blksz); 00312 CHECK_PAR((p_mpfcb->p_mpfinib->p_mpfmb + blkidx)->next == INDEX_ALLOC); 00313 00314 t_lock_cpu(); 00315 if (!queue_empty(&(p_mpfcb->wait_queue))) { 00316 p_tcb = (TCB *) queue_delete_next(&(p_mpfcb->wait_queue)); 00317 ((WINFO_MPF *)(p_tcb->p_winfo))->blk = blk; 00318 if (wait_complete(p_tcb)) { 00319 dispatch(); 00320 } 00321 ercd = E_OK; 00322 } 00323 else { 00324 p_mpfcb->fblkcnt++; 00325 (p_mpfcb->p_mpfinib->p_mpfmb + blkidx)->next = p_mpfcb->freelist; 00326 p_mpfcb->freelist = blkidx; 00327 ercd = E_OK; 00328 } 00329 t_unlock_cpu(); 00330 00331 error_exit: 00332 LOG_REL_MPF_LEAVE(ercd); 00333 return(ercd); 00334 } 00335 00336 #endif /* TOPPERS_rel_mpf */ 00337 00338 /* 00339 * 固定長メモリプールの再初期化 00340 */ 00341 #ifdef TOPPERS_ini_mpf 00342 00343 ER 00344 ini_mpf(ID mpfid) 00345 { 00346 MPFCB *p_mpfcb; 00347 bool_t dspreq; 00348 ER ercd; 00349 00350 LOG_INI_MPF_ENTER(mpfid); 00351 CHECK_TSKCTX_UNL(); 00352 CHECK_MPFID(mpfid); 00353 p_mpfcb = get_mpfcb(mpfid); 00354 00355 t_lock_cpu(); 00356 dspreq = init_wait_queue(&(p_mpfcb->wait_queue)); 00357 p_mpfcb->fblkcnt = p_mpfcb->p_mpfinib->blkcnt; 00358 p_mpfcb->unused = 0U; 00359 p_mpfcb->freelist = INDEX_NULL; 00360 if (dspreq) { 00361 dispatch(); 00362 } 00363 ercd = E_OK; 00364 t_unlock_cpu(); 00365 00366 error_exit: 00367 LOG_INI_MPF_LEAVE(ercd); 00368 return(ercd); 00369 } 00370 00371 #endif /* TOPPERS_ini_mpf */ 00372 00373 /* 00374 * 固定長メモリプールの状態参照 00375 */ 00376 #ifdef TOPPERS_ref_mpf 00377 00378 ER 00379 ref_mpf(ID mpfid, T_RMPF *pk_rmpf) 00380 { 00381 MPFCB *p_mpfcb; 00382 ER ercd; 00383 00384 LOG_REF_MPF_ENTER(mpfid, pk_rmpf); 00385 CHECK_TSKCTX_UNL(); 00386 CHECK_MPFID(mpfid); 00387 p_mpfcb = get_mpfcb(mpfid); 00388 00389 t_lock_cpu(); 00390 pk_rmpf->wtskid = wait_tskid(&(p_mpfcb->wait_queue)); 00391 pk_rmpf->fblkcnt = p_mpfcb->fblkcnt; 00392 ercd = E_OK; 00393 t_unlock_cpu(); 00394 00395 error_exit: 00396 LOG_REF_MPF_LEAVE(ercd, pk_rmpf); 00397 return(ercd); 00398 } 00399 00400 #endif /* TOPPERS_ref_mpf */
Copyright © 2008 by Kijineko Inc.