source: kernel/mempfix.c

このファイルの最終更新内容7 で kominami が 2015/09/12 9:22:12 に更新しました

TOPPERS/ASP 1.9.1

ファイルサイズ: 8.9 KB
Rev 
[7]1/*
2 *  TOPPERS/ASP Kernel
3 *      Toyohashi Open Platform for Embedded Real-Time Systems/
4 *      Advanced 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-2011 by Embedded and Real-Time Systems Laboratory
9 *              Graduate School of Information Science, Nagoya Univ., JAPAN
10 *
11 *  Ÿåµ­Ãøºîž¢ŒÔ€Ï¡€°Ê²Œ€Î(1)¡Á(4)€ÎŸò·ï€òËþ€¿€¹Ÿì¹ç€ËžÂ€ê¡€ËÜ¥œ¥Õ¥È¥Š¥§
12 *  ¥¢¡ÊËÜ¥œ¥Õ¥È¥Š¥§¥¢€ò²þÊÑ€·€¿€â€Î€òŽÞ€à¡¥°Ê²ŒÆ±€ž¡Ë€ò»ÈÍÑ¡ŠÊ£Àœ¡Š²þ
13 *  ÊÑ¡ŠºÆÇÛÉۡʰʲŒ¡€ÍøÍрȞƀ֡ˀ¹€ë€³€È€ò̵œþ€ÇµöÂú€¹€ë¡¥
14 *  (1) ËÜ¥œ¥Õ¥È¥Š¥§¥¢€ò¥œ¡Œ¥¹¥³¡Œ¥É€Î·Á€ÇÍøÍÑ€¹€ëŸì¹ç€Ë€Ï¡€Ÿåµ­€ÎÃøºî
15 *      ž¢ÉœŒš¡€€³€ÎÍøÍÑŸò·ï€ª€è€Ó²Œµ­€Î̵ÊÝŸÚµ¬Äꀬ¡€€œ€Î€Þ€Þ€Î·Á€Ç¥œ¡Œ
16 *      ¥¹¥³¡Œ¥ÉÃæ€ËŽÞ€Þ€ì€Æ€€€ë€³€È¡¥
17 *  (2) ËÜ¥œ¥Õ¥È¥Š¥§¥¢€ò¡€¥é¥€¥Ö¥é¥ê·ÁŒ°€Ê€É¡€ÂŸ€Î¥œ¥Õ¥È¥Š¥§¥¢³«È¯€Ë»È
18 *      Íрǀ­€ë·Á€ÇºÆÇÛÉÛ€¹€ëŸì¹ç€Ë€Ï¡€ºÆÇÛÉÛ€ËÈŒ€Š¥É¥­¥å¥á¥ó¥È¡ÊÍøÍÑ
19 *      ŒÔ¥Þ¥Ë¥å¥¢¥ë€Ê€É¡Ë€Ë¡€Ÿåµ­€ÎÃøºîž¢ÉœŒš¡€€³€ÎÍøÍÑŸò·ï€ª€è€Ó²Œµ­
20 *      €Î̵ÊÝŸÚµ¬Äê€ò·ÇºÜ€¹€ë€³€È¡¥
21 *  (3) ËÜ¥œ¥Õ¥È¥Š¥§¥¢€ò¡€µ¡Žï€ËÁȀ߹þ€à€Ê€É¡€ÂŸ€Î¥œ¥Õ¥È¥Š¥§¥¢³«È¯€Ë»È
22 *      Íрǀ­€Ê€€·Á€ÇºÆÇÛÉÛ€¹€ëŸì¹ç€Ë€Ï¡€Œ¡€Î€€€º€ì€«€ÎŸò·ï€òËþ€¿€¹€³
23 *      €È¡¥
24 *    (a) ºÆÇÛÉÛ€ËÈŒ€Š¥É¥­¥å¥á¥ó¥È¡ÊÍøÍьԥޥ˥奢¥ë€Ê€É¡Ë€Ë¡€Ÿåµ­€ÎÃø
25 *        ºîž¢ÉœŒš¡€€³€ÎÍøÍÑŸò·ï€ª€è€Ó²Œµ­€Î̵ÊÝŸÚµ¬Äê€ò·ÇºÜ€¹€ë€³€È¡¥
26 *    (b) ºÆÇÛÉۀηÁÂÖ€ò¡€ÊÌ€ËÄê€á€ëÊýË¡€Ë€è€Ã€Æ¡€TOPPERS¥×¥í¥ž¥§¥¯¥È€Ë
27 *        Êó¹ð€¹€ë€³€È¡¥
28 *  (4) ËÜ¥œ¥Õ¥È¥Š¥§¥¢€ÎÍøÍрˀè€êÄŸÀÜŪ€Þ€¿€ÏŽÖÀÜŪ€ËÀž€ž€ë€€€«€Ê€ë»
29 *      ³²€«€é€â¡€Ÿåµ­Ãøºîž¢ŒÔ€ª€è€ÓTOPPERS¥×¥í¥ž¥§¥¯¥È€òÌÈÀÕ€¹€ë€³€È¡¥
30 *      €Þ€¿¡€ËÜ¥œ¥Õ¥È¥Š¥§¥¢€Î¥æ¡Œ¥¶€Þ€¿€Ï¥š¥ó¥É¥æ¡Œ¥¶€«€é€Î€€€«€Ê€ëÍý
31 *      ͳ€ËŽð€Å€¯ÀÁµá€«€é€â¡€Ÿåµ­Ãøºîž¢ŒÔ€ª€è€ÓTOPPERS¥×¥í¥ž¥§¥¯¥È€ò
32 *      ÌÈÀÕ€¹€ë€³€È¡¥
33 *
34 *  ËÜ¥œ¥Õ¥È¥Š¥§¥¢€Ï¡€ÌµÊÝŸÚ€ÇÄó¶¡€µ€ì€Æ€€€ë€â€Î€Ç€¢€ë¡¥Ÿåµ­Ãøºîž¢ŒÔ€ª
35 *  €è€ÓTOPPERS¥×¥í¥ž¥§¥¯¥È€Ï¡€ËÜ¥œ¥Õ¥È¥Š¥§¥¢€ËŽØ€·€Æ¡€ÆÃÄê€Î»ÈÍÑÌÜŪ
36 *  €ËÂЀ¹€ëŬ¹çÀ­€âŽÞ€á€Æ¡€€€€«€Ê€ëÊÝŸÚ€â¹Ô€ï€Ê€€¡¥€Þ€¿¡€ËÜ¥œ¥Õ¥È¥Š¥§
37 *  ¥¢€ÎÍøÍрˀè€êÄŸÀÜŪ€Þ€¿€ÏŽÖÀÜŪ€ËÀž€ž€¿€€€«€Ê€ë»³²€ËŽØ€·€Æ€â¡€€œ
38 *  €ÎÀÕÇ€€òÉé€ï€Ê€€¡¥
39 *
40 *  @(#) $Id$
41 */
42
43/*
44 *              žÇÄêĹ¥á¥â¥ê¥×¡Œ¥ëµ¡Çœ
45 */
46
47#include "kernel_impl.h"
48#include "check.h"
49#include "task.h"
50#include "wait.h"
51#include "mempfix.h"
52
53/*
54 *  ¥È¥ì¡Œ¥¹¥í¥°¥Þ¥¯¥í€Î¥Ç¥Õ¥©¥ë¥ÈÄêµÁ
55 */
56#ifndef LOG_GET_MPF_ENTER
57#define LOG_GET_MPF_ENTER(mpfid, p_blk)
58#endif /* LOG_GET_MPF_ENTER */
59
60#ifndef LOG_GET_MPF_LEAVE
61#define LOG_GET_MPF_LEAVE(ercd, blk)
62#endif /* LOG_GET_MPF_LEAVE */
63
64#ifndef LOG_PGET_MPF_ENTER
65#define LOG_PGET_MPF_ENTER(mpfid, p_blk)
66#endif /* LOG_PGET_MPF_ENTER */
67
68#ifndef LOG_PGET_MPF_LEAVE
69#define LOG_PGET_MPF_LEAVE(ercd, blk)
70#endif /* LOG_PGET_MPF_LEAVE */
71
72#ifndef LOG_TGET_MPF_ENTER
73#define LOG_TGET_MPF_ENTER(mpfid, p_blk, tmout)
74#endif /* LOG_TGET_MPF_ENTER */
75
76#ifndef LOG_TGET_MPF_LEAVE
77#define LOG_TGET_MPF_LEAVE(ercd, blk)
78#endif /* LOG_TGET_MPF_LEAVE */
79
80#ifndef LOG_REL_MPF_ENTER
81#define LOG_REL_MPF_ENTER(mpfid, blk)
82#endif /* LOG_REL_MPF_ENTER */
83
84#ifndef LOG_REL_MPF_LEAVE
85#define LOG_REL_MPF_LEAVE(ercd)
86#endif /* LOG_REL_MPF_LEAVE */
87
88#ifndef LOG_INI_MPF_ENTER
89#define LOG_INI_MPF_ENTER(mpfid)
90#endif /* LOG_INI_MPF_ENTER */
91
92#ifndef LOG_INI_MPF_LEAVE
93#define LOG_INI_MPF_LEAVE(ercd)
94#endif /* LOG_INI_MPF_LEAVE */
95
96#ifndef LOG_REF_MPF_ENTER
97#define LOG_REF_MPF_ENTER(mpfid, pk_rmpf)
98#endif /* LOG_REF_MPF_ENTER */
99
100#ifndef LOG_REF_MPF_LEAVE
101#define LOG_REF_MPF_LEAVE(ercd, pk_rmpf)
102#endif /* LOG_REF_MPF_LEAVE */
103
104/*
105 *  žÇÄêĹ¥á¥â¥ê¥×¡Œ¥ë€Î¿ô
106 */
107#define tnum_mpf        ((uint_t)(tmax_mpfid - TMIN_MPFID + 1))
108
109/*
110 *  žÇÄêĹ¥á¥â¥ê¥×¡Œ¥ëID€«€éžÇÄêĹ¥á¥â¥ê¥×¡Œ¥ëŽÉÍý¥Ö¥í¥Ã¥¯€òŒè€êœÐ€¹€¿
111 *  €á€Î¥Þ¥¯¥í
112 */
113#define INDEX_MPF(mpfid)        ((uint_t)((mpfid) - TMIN_MPFID))
114#define get_mpfcb(mpfid)        (&(mpfcb_table[INDEX_MPF(mpfid)]))
115
116/*
117 *  ÆÃŒì€Ê¥€¥ó¥Ç¥Ã¥¯¥¹ÃÍ€ÎÄêµÁ
118 */
119#define INDEX_NULL              (~0U)           /* ¶õ€­¥Ö¥í¥Ã¥¯¥ê¥¹¥È€ÎºÇžå */
120#define INDEX_ALLOC             (~1U)           /* ³äÅö€ÆºÑ€ß€Î¥Ö¥í¥Ã¥¯ */
121
122/*
123 *  žÇÄêĹ¥á¥â¥ê¥×¡Œ¥ëµ¡Çœ€ÎœéŽü²œ
124 */
125#ifdef TOPPERS_mpfini
126
127void
128initialize_mempfix(void)
129{
130        uint_t  i;
131        MPFCB   *p_mpfcb;
132
133        for (i = 0; i < tnum_mpf; i++) {
134                p_mpfcb = &(mpfcb_table[i]);
135                queue_initialize(&(p_mpfcb->wait_queue));
136                p_mpfcb->p_mpfinib = &(mpfinib_table[i]);
137                p_mpfcb->fblkcnt = p_mpfcb->p_mpfinib->blkcnt;
138                p_mpfcb->unused = 0U;
139                p_mpfcb->freelist = INDEX_NULL;
140        }
141}
142
143#endif /* TOPPERS_mpfini */
144
145/*
146 *  žÇÄêĹ¥á¥â¥ê¥×¡Œ¥ë€«€é¥Ö¥í¥Ã¥¯€ò³ÍÆÀ
147 */
148#ifdef TOPPERS_mpfget
149
150void
151get_mpf_block(MPFCB *p_mpfcb, void **p_blk)
152{
153        uint_t  blkidx;
154
155        if (p_mpfcb->freelist != INDEX_NULL) {
156                blkidx = p_mpfcb->freelist;
157                p_mpfcb->freelist = (p_mpfcb->p_mpfinib->p_mpfmb + blkidx)->next;
158        }
159        else {
160                blkidx = p_mpfcb->unused;
161                p_mpfcb->unused++;
162        }
163        *p_blk = (void *)((char *)(p_mpfcb->p_mpfinib->mpf)
164                                                                + p_mpfcb->p_mpfinib->blksz * blkidx);
165        p_mpfcb->fblkcnt--;
166        (p_mpfcb->p_mpfinib->p_mpfmb + blkidx)->next = INDEX_ALLOC;
167}
168
169#endif /* TOPPERS_mpfget */
170
171/*
172 *  žÇÄêĹ¥á¥â¥ê¥Ö¥í¥Ã¥¯€Î³ÍÆÀ
173 */
174#ifdef TOPPERS_get_mpf
175
176ER
177get_mpf(ID mpfid, void **p_blk)
178{
179        MPFCB   *p_mpfcb;
180        WINFO_MPF winfo_mpf;
181        ER              ercd;
182
183        LOG_GET_MPF_ENTER(mpfid, p_blk);
184        CHECK_DISPATCH();
185        CHECK_MPFID(mpfid);
186        p_mpfcb = get_mpfcb(mpfid);
187
188        t_lock_cpu();
189        if (p_mpfcb->fblkcnt > 0) {
190                get_mpf_block(p_mpfcb, p_blk);
191                ercd = E_OK;
192        }
193        else {
194                p_runtsk->tstat = (TS_WAITING | TS_WAIT_MPF);
195                wobj_make_wait((WOBJCB *) p_mpfcb, (WINFO_WOBJ *) &winfo_mpf);
196                dispatch();
197                ercd = winfo_mpf.winfo.wercd;
198                if (ercd == E_OK) {
199                        *p_blk = winfo_mpf.blk;
200                }
201        }
202        t_unlock_cpu();
203
204  error_exit:
205        LOG_GET_MPF_LEAVE(ercd, *p_blk);
206        return(ercd);
207}
208
209#endif /* TOPPERS_get_mpf */
210
211/*
212 *  žÇÄêĹ¥á¥â¥ê¥Ö¥í¥Ã¥¯€Î³ÍÆÀ¡Ê¥Ý¡Œ¥ê¥ó¥°¡Ë
213 */
214#ifdef TOPPERS_pget_mpf
215
216ER
217pget_mpf(ID mpfid, void **p_blk)
218{
219        MPFCB   *p_mpfcb;
220        ER              ercd;
221
222        LOG_PGET_MPF_ENTER(mpfid, p_blk);
223        CHECK_TSKCTX_UNL();
224        CHECK_MPFID(mpfid);
225        p_mpfcb = get_mpfcb(mpfid);
226
227        t_lock_cpu();
228        if (p_mpfcb->fblkcnt > 0) {
229                get_mpf_block(p_mpfcb, p_blk);
230                ercd = E_OK;
231        }
232        else {
233                ercd = E_TMOUT;
234        }
235        t_unlock_cpu();
236
237  error_exit:
238        LOG_PGET_MPF_LEAVE(ercd, *p_blk);
239        return(ercd);
240}
241
242#endif /* TOPPERS_pget_mpf */
243
244/*
245 *  žÇÄêĹ¥á¥â¥ê¥Ö¥í¥Ã¥¯€Î³ÍÆÀ¡Ê¥¿¥€¥à¥¢¥Š¥È€¢€ê¡Ë
246 */
247#ifdef TOPPERS_tget_mpf
248
249ER
250tget_mpf(ID mpfid, void **p_blk, TMO tmout)
251{
252        MPFCB   *p_mpfcb;
253        WINFO_MPF winfo_mpf;
254        TMEVTB  tmevtb;
255        ER              ercd;
256
257        LOG_TGET_MPF_ENTER(mpfid, p_blk, tmout);
258        CHECK_DISPATCH();
259        CHECK_MPFID(mpfid);
260        CHECK_TMOUT(tmout);
261        p_mpfcb = get_mpfcb(mpfid);
262
263        t_lock_cpu();
264        if (p_mpfcb->fblkcnt > 0) {
265                get_mpf_block(p_mpfcb, p_blk);
266                ercd = E_OK;
267        }
268        else if (tmout == TMO_POL) {
269                ercd = E_TMOUT;
270        }
271        else {
272                p_runtsk->tstat = (TS_WAITING | TS_WAIT_MPF);
273                wobj_make_wait_tmout((WOBJCB *) p_mpfcb, (WINFO_WOBJ *) &winfo_mpf,
274                                                                                                                &tmevtb, tmout);
275                dispatch();
276                ercd = winfo_mpf.winfo.wercd;
277                if (ercd == E_OK) {
278                        *p_blk = winfo_mpf.blk;
279                }
280        }
281        t_unlock_cpu();
282
283  error_exit:
284        LOG_TGET_MPF_LEAVE(ercd, *p_blk);
285        return(ercd);
286}
287
288#endif /* TOPPERS_tget_mpf */
289
290/*
291 *  žÇÄêĹ¥á¥â¥ê¥Ö¥í¥Ã¥¯€ÎÊÖµÑ
292 */
293#ifdef TOPPERS_rel_mpf
294
295ER
296rel_mpf(ID mpfid, void *blk)
297{
298        MPFCB   *p_mpfcb;
299        SIZE    blkoffset;
300        uint_t  blkidx;
301        TCB             *p_tcb;
302        ER              ercd;
303   
304        LOG_REL_MPF_ENTER(mpfid, blk);
305        CHECK_TSKCTX_UNL();
306        CHECK_MPFID(mpfid);
307        p_mpfcb = get_mpfcb(mpfid);
308        CHECK_PAR(p_mpfcb->p_mpfinib->mpf <= blk);
309        blkoffset = ((char *) blk) - (char *)(p_mpfcb->p_mpfinib->mpf);
310        CHECK_PAR(blkoffset % p_mpfcb->p_mpfinib->blksz == 0U);
311        CHECK_PAR(blkoffset / p_mpfcb->p_mpfinib->blksz < p_mpfcb->unused);
312        blkidx = (uint_t)(blkoffset / p_mpfcb->p_mpfinib->blksz);
313        CHECK_PAR((p_mpfcb->p_mpfinib->p_mpfmb + blkidx)->next == INDEX_ALLOC);
314
315        t_lock_cpu();
316        if (!queue_empty(&(p_mpfcb->wait_queue))) {
317                p_tcb = (TCB *) queue_delete_next(&(p_mpfcb->wait_queue));
318                ((WINFO_MPF *)(p_tcb->p_winfo))->blk = blk;
319                if (wait_complete(p_tcb)) {
320                        dispatch();
321                }
322                ercd = E_OK;
323        }
324        else {
325                p_mpfcb->fblkcnt++;
326                (p_mpfcb->p_mpfinib->p_mpfmb + blkidx)->next = p_mpfcb->freelist;
327                p_mpfcb->freelist = blkidx;
328                ercd = E_OK;
329        }
330        t_unlock_cpu();
331
332  error_exit:
333        LOG_REL_MPF_LEAVE(ercd);
334        return(ercd);
335}
336
337#endif /* TOPPERS_rel_mpf */
338
339/*
340 *  žÇÄêĹ¥á¥â¥ê¥×¡Œ¥ë€ÎºÆœéŽü²œ
341 */
342#ifdef TOPPERS_ini_mpf
343
344ER
345ini_mpf(ID mpfid)
346{
347        MPFCB   *p_mpfcb;
348        bool_t  dspreq;
349        ER              ercd;
350   
351        LOG_INI_MPF_ENTER(mpfid);
352        CHECK_TSKCTX_UNL();
353        CHECK_MPFID(mpfid);
354        p_mpfcb = get_mpfcb(mpfid);
355
356        t_lock_cpu();
357        dspreq = init_wait_queue(&(p_mpfcb->wait_queue));
358        p_mpfcb->fblkcnt = p_mpfcb->p_mpfinib->blkcnt;
359        p_mpfcb->unused = 0U;
360        p_mpfcb->freelist = INDEX_NULL;
361        if (dspreq) {
362                dispatch();
363        }
364        ercd = E_OK;
365        t_unlock_cpu();
366
367  error_exit:
368        LOG_INI_MPF_LEAVE(ercd);
369        return(ercd);
370}
371
372#endif /* TOPPERS_ini_mpf */
373
374/*
375 *  žÇÄêĹ¥á¥â¥ê¥×¡Œ¥ë€ÎŸõÂÖ»²ŸÈ
376 */
377#ifdef TOPPERS_ref_mpf
378
379ER
380ref_mpf(ID mpfid, T_RMPF *pk_rmpf)
381{
382        MPFCB   *p_mpfcb;
383        ER              ercd;
384   
385        LOG_REF_MPF_ENTER(mpfid, pk_rmpf);
386        CHECK_TSKCTX_UNL();
387        CHECK_MPFID(mpfid);
388        p_mpfcb = get_mpfcb(mpfid);
389
390        t_lock_cpu();
391        pk_rmpf->wtskid = wait_tskid(&(p_mpfcb->wait_queue));
392        pk_rmpf->fblkcnt = p_mpfcb->fblkcnt;
393        ercd = E_OK;
394        t_unlock_cpu();
395
396  error_exit:
397        LOG_REF_MPF_LEAVE(ercd, pk_rmpf);
398        return(ercd);
399}
400
401#endif /* TOPPERS_ref_mpf */
詳しい使い方は TracBrowser を参照してください。