mempfix.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: mempfix.c,v 1.3 2006/03/14 04:37:54 honda Exp $
00039  */
00040 
00046 #include "fdmp_kernel.h"
00047 #include "check.h"
00048 #include "task.h"
00049 #include "wait.h"
00050 #include "mempfix.h"
00051 
00055 extern const ID tmax_mpfid;
00056 
00060 extern const MPFINIB    mpfinib_table[];
00061 
00065 extern MPFCB    mpfcb_table[];
00066 
00070 #define TNUM_MPF    ((UINT)(tmax_mpfid - TMIN_ID + 1))
00071 
00072 /*
00073  *  固定長メモリプールIDから固定長メモリプール管理ブロックを取り出すた
00074  *  めのマクロ
00075  */
00076 #define INDEX_MPF(mpfid)    ((UINT)((mpfid) - TMIN_ID))
00077 #define get_mpfcb(ccb, mpfid)   (&(((MPFCB *)(ccb->mpf.cb_table))[INDEX_MPF(mpfid)]))
00078 
00079 
00083 typedef struct fixed_memorypool_waiting_information {
00084     WINFO   winfo;      /* 標準の待ち情報ブロック */
00085     WOBJCB  *wobjcb;    /* 待ちオブジェクトの管理ブロック */
00086     CCB *ccb;           /* オブジェクトが所属するクラスID */
00087     VP  blk;            /* 獲得したメモリブロック */
00088 } WINFO_MPF;
00089 
00090 
00094 #ifdef __mpfini
00095 
00096 void
00097 mempfix_initialize()
00098 {
00099     UINT    i;
00100     MPFCB   *mpfcb;
00101 
00102     for (mpfcb = mpfcb_table, i = 0; i < TNUM_MPF; mpfcb++, i++) {
00103         queue_initialize(&(mpfcb->wait_queue));
00104         mpfcb->mpfinib = &(mpfinib_table[i]);
00105         mpfcb->unused = mpfcb->mpfinib->mpf;
00106         mpfcb->freelist = NULL;
00107     }
00108 
00109     my_local_exccb->mpf.cb_table = &mpfcb_table[0];
00110     my_local_exccb->mpf.max_id   = tmax_mpfid;
00111 }
00112 
00113 #endif /* __mpfini */
00114 
00118 #ifdef __mpfget
00119 
00120 BOOL
00121 mempfix_get_block(MPFCB *mpfcb, VP *p_blk)
00122 {
00123     FREEL   *free;
00124 
00125     if (mpfcb->freelist != NULL) {
00126         free = mpfcb->freelist;
00127         mpfcb->freelist = free->next;
00128         *p_blk = (VP) free;
00129         return(TRUE);
00130     }
00131     else if (mpfcb->unused < mpfcb->mpfinib->limit) {
00132         *p_blk = mpfcb->unused;
00133         mpfcb->unused = (VP)((SIZE)(mpfcb->unused)
00134                         + mpfcb->mpfinib->blksz);
00135         return(TRUE);
00136     }
00137     return(FALSE);
00138 }
00139 
00140 #endif /* __mpfget */
00141 
00145 #ifdef __get_mpf
00146 
00147 SYSCALL ER
00148 get_mpf(ID mpfid, VP *p_blk)
00149 {
00150     MPFCB   *mpfcb;
00151     WINFO_MPF winfo;
00152     ER      ercd;
00153     CCB     *ccb;
00154 
00155     LOG_GET_MPF_ENTER(mpfid, p_blk);
00156     CHECK_DISPATCH();
00157     ccb = T_CHECK_CLSID_CCB(mpfid);
00158     mpfid = remove_clsid(mpfid);
00159     CHECK_MPFID(ccb, mpfid);
00160     mpfcb = get_mpfcb(ccb, mpfid);
00161     
00162   retry:
00163     T_ACQUIRE_LOCK(ccb->obj_lock);
00164     if (mempfix_get_block(mpfcb, p_blk)) {
00165         RELEASE_LOCK(ccb->obj_lock);
00166         ercd = E_OK;
00167     }
00168     else {
00169         T_ACQUIRE_NESTED_LOCK_AND_CHECK_RUNNABLE(ccb->obj_lock);
00170         wobj_make_wait(ccb, (WOBJCB *) mpfcb, (WINFO_WOBJ *) &winfo);
00171         T_RELEASE_NESTED_LOCK(runccb->tsk_lock, ccb->obj_lock);
00172         RELEASE_LOCK(ccb->obj_lock);
00173         dispatch();
00174         ercd = winfo.winfo.wercd;
00175         if (ercd == E_OK) {
00176             *p_blk = winfo.blk;
00177         }
00178     }
00179     t_unlock_cpu();
00180 
00181   exit:
00182     LOG_GET_MPF_LEAVE(ercd, *p_blk);
00183     return(ercd);
00184 }
00185 
00186 #endif /* __get_mpf */
00187 
00191 #ifdef __pget_mpf
00192 
00193 SYSCALL ER
00194 pget_mpf(ID mpfid, VP *p_blk)
00195 {
00196     MPFCB   *mpfcb;
00197     ER      ercd;
00198     CCB     *ccb;
00199     
00200     LOG_PGET_MPF_ENTER(mpfid, p_blk);
00201     CHECK_TSKCTX_UNL();
00202     ccb = T_CHECK_CLSID_CCB(mpfid);
00203     mpfid = remove_clsid(mpfid);
00204     CHECK_MPFID(ccb, mpfid);
00205     mpfcb = get_mpfcb(ccb, mpfid);
00206 
00207   retry:
00208     T_ACQUIRE_LOCK(ccb->obj_lock);
00209     if (mempfix_get_block(mpfcb, p_blk)) {
00210         ercd = E_OK;
00211     }
00212     else {
00213         ercd = E_TMOUT;
00214     }
00215     T_RELEASE_LOCK(ccb->obj_lock);
00216 
00217   exit:
00218     LOG_PGET_MPF_LEAVE(ercd, *p_blk);
00219     return(ercd);
00220 }
00221 
00222 #endif /* __pget_mpf */
00223 
00227 #ifdef __tget_mpf
00228 
00229 SYSCALL ER
00230 tget_mpf(ID mpfid, VP *p_blk, TMO tmout)
00231 {
00232     MPFCB   *mpfcb;
00233     WINFO_MPF winfo;
00234     TMEVTB  tmevtb;
00235     ER      ercd = E_OK;
00236     CCB     *ccb;
00237 
00238     LOG_TGET_MPF_ENTER(mpfid, p_blk, tmout);
00239     CHECK_DISPATCH();
00240     ccb = T_CHECK_CLSID_CCB(mpfid);
00241     mpfid = remove_clsid(mpfid);
00242     CHECK_MPFID(ccb, mpfid);
00243     CHECK_TMOUT(tmout);
00244     mpfcb = get_mpfcb(ccb, mpfid);
00245 
00246   retry:
00247     T_ACQUIRE_LOCK(ccb->obj_lock);
00248     if (mempfix_get_block(mpfcb, p_blk)) {
00249         RELEASE_LOCK(ccb->obj_lock);
00250         ercd = E_OK;
00251     }
00252     else if (tmout == TMO_POL) {
00253         RELEASE_LOCK(ccb->obj_lock);
00254         ercd = E_TMOUT;
00255     }
00256     else {
00257         T_ACQUIRE_NESTED_LOCK_AND_CHECK_RUNNABLE(ccb->obj_lock);
00258         wobj_make_wait_tmout(ccb, (WOBJCB *) mpfcb, (WINFO_WOBJ *) &winfo,
00259                         &tmevtb, tmout);
00260         T_RELEASE_NESTED_LOCK(runccb->tsk_lock, ccb->obj_lock);
00261         RELEASE_LOCK(ccb->obj_lock);
00262         LOG_TSKSTAT(runtsk);
00263         dispatch();     
00264         ercd = winfo.winfo.wercd;
00265         if (ercd == E_OK) {
00266             *p_blk = winfo.blk;
00267         }
00268     }
00269     t_unlock_cpu();
00270 
00271   exit:
00272     LOG_TGET_MPF_LEAVE(ercd, *p_blk);
00273     return(ercd);
00274 }
00275 
00276 #endif /* __tget_mpf */
00277 
00281 #ifdef __rel_mpf
00282 
00283 SYSCALL ER
00284 rel_mpf(ID mpfid, VP blk)
00285 {
00286     MPFCB   *mpfcb;
00287     TCB     *tcb;
00288     FREEL   *free;
00289     ER      ercd;
00290     CCB     *ccb, *tccb;
00291     BOOL    dspreq = FALSE;
00292     
00293     LOG_REL_MPF_ENTER(mpfid, blk);
00294     CHECK_TSKCTX_UNL();
00295     ccb = T_CHECK_CLSID_CCB(mpfid);
00296     mpfid = remove_clsid(mpfid);
00297     CHECK_MPFID(ccb, mpfid);
00298     mpfcb = get_mpfcb(ccb, mpfid);  
00299     CHECK_PAR(mpfcb->mpfinib->mpf <= blk
00300             && blk < mpfcb->mpfinib->limit
00301             && ((SIZE)(blk) - (SIZE)(mpfcb->mpfinib->mpf))
00302                     % mpfcb->mpfinib->blksz == 0);
00303 
00304   retry:
00305     T_ACQUIRE_LOCK(ccb->obj_lock);
00306     if (!(queue_empty(&(mpfcb->wait_queue)))) {
00307         /*
00308          * T_ACQUIRE_NESTED_LOCK()は,T_ACQUIRE_LOCK()との間をリトライで
00309          * 繰り返し実行するため,この間非破壊コードでなければならない.
00310          */      
00311         tcb = (TCB *) (mpfcb->wait_queue.next);
00312         tccb = get_ccb(tcb->clsid);     
00313         ((WINFO_MPF *)(tcb->winfo))->blk = blk;
00314         T_ACQUIRE_NESTED_LOCK(tccb->tsk_lock, ccb->obj_lock);
00315         /* 待ちキューから削除する */
00316         queue_delete_next(&(mpfcb->wait_queue));
00317         if (wait_complete(tccb, tcb)) {
00318             dspreq = dispatch_request(tccb->prcid);
00319         }
00320         T_RELEASE_NESTED_LOCK(tccb->tsk_lock, ccb->obj_lock);
00321         ercd = E_OK;
00322     }
00323     else {
00324         free = (FREEL *) blk;
00325         free->next = mpfcb->freelist;
00326         mpfcb->freelist = free;
00327         ercd = E_OK;
00328     }
00329     T_RELEASE_LOCK_AND_DISPATCH(ccb->obj_lock, dspreq);
00330 
00331     exit:
00332     LOG_REL_MPF_LEAVE(ercd);
00333     return(ercd);
00334 }
00335 
00336 #endif /* __rel_mpf */

Copyright © 2006 by TAKAGI Nobuhisa.
このページは Mon Apr 3 23:49:12 2006 に Doxygen によって生成されました。