mempfix.c

説明を見る。
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.

ホームページ制作