OSDN Git Service

Change the directry name to hirado
[trx-305dsp/dsp.git] / hirado / kernel / kernel / mempfix.c
1 /*
2  *  TOPPERS/JSP Kernel
3  *      Toyohashi Open Platform for Embedded Real-Time Systems/
4  *      Just Standard Profile Kernel
5  * 
6  *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7  *                              Toyohashi Univ. of Technology, JAPAN
8  *  Copyright (C) 2005 by Embedded and Real-Time Systems Laboratory
9  *              Graduate School of Information Science, Nagoya Univ., JAPAN
10  * 
11  *  上記著作権者は,以下の (1)〜(4) の条件か,Free Software Foundation 
12  *  によって公表されている GNU General Public License の Version 2 に記
13  *  述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
14  *  を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
15  *  利用と呼ぶ)することを無償で許諾する.
16  *  (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
17  *      権表示,この利用条件および下記の無保証規定が,そのままの形でソー
18  *      スコード中に含まれていること.
19  *  (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
20  *      用できる形で再配布する場合には,再配布に伴うドキュメント(利用
21  *      者マニュアルなど)に,上記の著作権表示,この利用条件および下記
22  *      の無保証規定を掲載すること.
23  *  (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
24  *      用できない形で再配布する場合には,次のいずれかの条件を満たすこ
25  *      と.
26  *    (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
27  *        作権表示,この利用条件および下記の無保証規定を掲載すること.
28  *    (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
29  *        報告すること.
30  *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
31  *      害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
32  * 
33  *  本ソフトウェアは,無保証で提供されているものである.上記著作権者お
34  *  よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
35  *  含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
36  *  接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
37  * 
38  *  @(#) $Id: mempfix.c,v 1.1 2009/01/31 05:27:37 suikan Exp $
39  */
40
41 /*
42  *  固定長メモリプール機能
43  */
44
45 #include "jsp_kernel.h"
46 #include "check.h"
47 #include "task.h"
48 #include "wait.h"
49 #include "mempfix.h"
50
51 /*
52  *  固定長メモリプールIDの最大値(kernel_cfg.c)
53  */
54 extern const ID tmax_mpfid;
55
56 /*
57  *  固定長メモリプール初期化ブロックのエリア(kernel_cfg.c)
58  */
59 extern const MPFINIB    mpfinib_table[];
60
61 /*
62  *  固定長メモリプール管理ブロックのエリア(kernel_cfg.c)
63  */
64 extern MPFCB    mpfcb_table[];
65
66 /*
67  *  固定長メモリプールの数
68  */
69 #define TNUM_MPF    ((UINT)(tmax_mpfid - TMIN_MPFID + 1))
70
71 /*
72  *  固定長メモリプールIDから固定長メモリプール管理ブロックを取り出すた
73  *  めのマクロ
74  */
75 #define INDEX_MPF(mpfid)    ((UINT)((mpfid) - TMIN_MPFID))
76 #define get_mpfcb(mpfid)    (&(mpfcb_table[INDEX_MPF(mpfid)]))
77
78 /*
79  *  固定長メモリプール待ち情報ブロックの定義
80  */
81 typedef struct fixed_memorypool_waiting_information {
82     WINFO   winfo;      /* 標準の待ち情報ブロック */
83     WOBJCB  *wobjcb;    /* 待ちオブジェクトの管理ブロック */
84     VP  blk;        /* 獲得したメモリブロック */
85 } WINFO_MPF;
86
87 /* 
88  *  固定長メモリプール機能の初期化
89  */
90 #ifdef __mpfini
91
92 void
93 mempfix_initialize()
94 {
95     UINT    i;
96     MPFCB   *mpfcb;
97
98     for (mpfcb = mpfcb_table, i = 0; i < TNUM_MPF; mpfcb++, i++) {
99         queue_initialize(&(mpfcb->wait_queue));
100         mpfcb->mpfinib = &(mpfinib_table[i]);
101         mpfcb->unused = mpfcb->mpfinib->mpf;
102         mpfcb->freelist = NULL;
103     }
104 }
105
106 #endif /* __mpfini */
107
108 /*
109  *  固定長メモリプールからブロックを獲得
110  */
111 #ifdef __mpfget
112
113 BOOL
114 mempfix_get_block(MPFCB *mpfcb, VP *p_blk)
115 {
116     FREEL   *free;
117
118     if (mpfcb->freelist != NULL) {
119         free = mpfcb->freelist;
120         mpfcb->freelist = free->next;
121         *p_blk = (VP) free;
122         return(TRUE);
123     }
124     else if (mpfcb->unused < mpfcb->mpfinib->limit) {
125         *p_blk = mpfcb->unused;
126         mpfcb->unused = (VP)((char *)(mpfcb->unused)
127                         + mpfcb->mpfinib->blksz);
128         return(TRUE);
129     }
130     return(FALSE);
131 }
132
133 #endif /* __mpfget */
134
135 /*
136  *  固定長メモリブロックの獲得
137  */
138 #ifdef __get_mpf
139
140 SYSCALL ER
141 get_mpf(ID mpfid, VP *p_blk)
142 {
143     MPFCB   *mpfcb;
144     WINFO_MPF winfo;
145     ER  ercd;
146
147     LOG_GET_MPF_ENTER(mpfid, p_blk);
148     CHECK_DISPATCH();
149     CHECK_MPFID(mpfid);
150     mpfcb = get_mpfcb(mpfid);
151
152     t_lock_cpu();
153     if (mempfix_get_block(mpfcb, p_blk)) {
154         ercd = E_OK;
155     }
156     else {
157         wobj_make_wait((WOBJCB *) mpfcb, (WINFO_WOBJ *) &winfo);
158         dispatch();
159         ercd = winfo.winfo.wercd;
160         if (ercd == E_OK) {
161             *p_blk = winfo.blk;
162         }
163     }
164     t_unlock_cpu();
165
166     exit:
167     LOG_GET_MPF_LEAVE(ercd, *p_blk);
168     return(ercd);
169 }
170
171 #endif /* __get_mpf */
172
173 /*
174  *  固定長メモリブロックの獲得(ポーリング)
175  */
176 #ifdef __pget_mpf
177
178 SYSCALL ER
179 pget_mpf(ID mpfid, VP *p_blk)
180 {
181     MPFCB   *mpfcb;
182     ER  ercd;
183
184     LOG_PGET_MPF_ENTER(mpfid, p_blk);
185     CHECK_TSKCTX_UNL();
186     CHECK_MPFID(mpfid);
187     mpfcb = get_mpfcb(mpfid);
188
189     t_lock_cpu();
190     if (mempfix_get_block(mpfcb, p_blk)) {
191         ercd = E_OK;
192     }
193     else {
194         ercd = E_TMOUT;
195     }
196     t_unlock_cpu();
197
198     exit:
199     LOG_PGET_MPF_LEAVE(ercd, *p_blk);
200     return(ercd);
201 }
202
203 #endif /* __pget_mpf */
204
205 /*
206  *  固定長メモリブロックの獲得(タイムアウトあり)
207  */
208 #ifdef __tget_mpf
209
210 SYSCALL ER
211 tget_mpf(ID mpfid, VP *p_blk, TMO tmout)
212 {
213     MPFCB   *mpfcb;
214     WINFO_MPF winfo;
215     TMEVTB  tmevtb;
216     ER  ercd;
217
218     LOG_TGET_MPF_ENTER(mpfid, p_blk, tmout);
219     CHECK_DISPATCH();
220     CHECK_MPFID(mpfid);
221     CHECK_TMOUT(tmout);
222     mpfcb = get_mpfcb(mpfid);
223
224     t_lock_cpu();
225     if (mempfix_get_block(mpfcb, p_blk)) {
226         ercd = E_OK;
227     }
228     else if (tmout == TMO_POL) {
229         ercd = E_TMOUT;
230     }
231     else {
232         wobj_make_wait_tmout((WOBJCB *) mpfcb, (WINFO_WOBJ *) &winfo,
233                         &tmevtb, tmout);
234         dispatch();
235         ercd = winfo.winfo.wercd;
236         if (ercd == E_OK) {
237             *p_blk = winfo.blk;
238         }
239     }
240     t_unlock_cpu();
241
242     exit:
243     LOG_TGET_MPF_LEAVE(ercd, *p_blk);
244     return(ercd);
245 }
246
247 #endif /* __tget_mpf */
248
249 /*
250  *  固定長メモリブロックの返却
251  */
252 #ifdef __rel_mpf
253
254 SYSCALL ER
255 rel_mpf(ID mpfid, VP blk)
256 {
257     MPFCB   *mpfcb;
258     TCB *tcb;
259     FREEL   *free;
260     ER  ercd;
261     
262     LOG_REL_MPF_ENTER(mpfid, blk);
263     CHECK_TSKCTX_UNL();
264     CHECK_MPFID(mpfid);
265     mpfcb = get_mpfcb(mpfid);
266     CHECK_PAR(mpfcb->mpfinib->mpf <= blk
267             && blk < mpfcb->mpfinib->limit
268             && ((char *)(blk) - (char *)(mpfcb->mpfinib->mpf))
269                     % mpfcb->mpfinib->blksz == 0);
270
271     t_lock_cpu();
272     if (!(queue_empty(&(mpfcb->wait_queue)))) {
273         tcb = (TCB *) queue_delete_next(&(mpfcb->wait_queue));
274         ((WINFO_MPF *)(tcb->winfo))->blk = blk;
275         if (wait_complete(tcb)) {
276             dispatch();
277         }
278         ercd = E_OK;
279     }
280     else {
281         free = (FREEL *) blk;
282         free->next = mpfcb->freelist;
283         mpfcb->freelist = free;
284         ercd = E_OK;
285     }
286     t_unlock_cpu();
287
288     exit:
289     LOG_REL_MPF_LEAVE(ercd);
290     return(ercd);
291 }
292
293 #endif /* __rel_mpf */