3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Advanced Standard Profile Kernel
6 * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
8 * Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
9 * Graduate School of Information Science, Nagoya Univ., JAPAN
11 * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
12 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
13 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
14 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
15 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
17 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
18 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
19 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
21 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
22 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
24 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
25 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
26 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
28 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
29 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
30 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
31 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
34 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
35 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
36 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
37 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
40 * @(#) $Id: mempfix.c 1966 2010-11-20 07:23:56Z ertl-hiro $
47 #include "kernel_impl.h"
56 #ifndef LOG_ACRE_MPF_ENTER
57 #define LOG_ACRE_MPF_ENTER(pk_cmpf)
58 #endif /* LOG_ACRE_MPF_ENTER */
60 #ifndef LOG_ACRE_MPF_LEAVE
61 #define LOG_ACRE_MPF_LEAVE(ercd)
62 #endif /* LOG_ACRE_MPF_LEAVE */
64 #ifndef LOG_DEL_MPF_ENTER
65 #define LOG_DEL_MPF_ENTER(mpfid)
66 #endif /* LOG_DEL_MPF_ENTER */
68 #ifndef LOG_DEL_MPF_LEAVE
69 #define LOG_DEL_MPF_LEAVE(ercd)
70 #endif /* LOG_DEL_MPF_LEAVE */
72 #ifndef LOG_GET_MPF_ENTER
73 #define LOG_GET_MPF_ENTER(mpfid, p_blk)
74 #endif /* LOG_GET_MPF_ENTER */
76 #ifndef LOG_GET_MPF_LEAVE
77 #define LOG_GET_MPF_LEAVE(ercd, blk)
78 #endif /* LOG_GET_MPF_LEAVE */
80 #ifndef LOG_PGET_MPF_ENTER
81 #define LOG_PGET_MPF_ENTER(mpfid, p_blk)
82 #endif /* LOG_PGET_MPF_ENTER */
84 #ifndef LOG_PGET_MPF_LEAVE
85 #define LOG_PGET_MPF_LEAVE(ercd, blk)
86 #endif /* LOG_PGET_MPF_LEAVE */
88 #ifndef LOG_TGET_MPF_ENTER
89 #define LOG_TGET_MPF_ENTER(mpfid, p_blk, tmout)
90 #endif /* LOG_TGET_MPF_ENTER */
92 #ifndef LOG_TGET_MPF_LEAVE
93 #define LOG_TGET_MPF_LEAVE(ercd, blk)
94 #endif /* LOG_TGET_MPF_LEAVE */
96 #ifndef LOG_REL_MPF_ENTER
97 #define LOG_REL_MPF_ENTER(mpfid, blk)
98 #endif /* LOG_REL_MPF_ENTER */
100 #ifndef LOG_REL_MPF_LEAVE
101 #define LOG_REL_MPF_LEAVE(ercd)
102 #endif /* LOG_REL_MPF_LEAVE */
104 #ifndef LOG_INI_MPF_ENTER
105 #define LOG_INI_MPF_ENTER(mpfid)
106 #endif /* LOG_INI_MPF_ENTER */
108 #ifndef LOG_INI_MPF_LEAVE
109 #define LOG_INI_MPF_LEAVE(ercd)
110 #endif /* LOG_INI_MPF_LEAVE */
112 #ifndef LOG_REF_MPF_ENTER
113 #define LOG_REF_MPF_ENTER(mpfid, pk_rmpf)
114 #endif /* LOG_REF_MPF_ENTER */
116 #ifndef LOG_REF_MPF_LEAVE
117 #define LOG_REF_MPF_LEAVE(ercd, pk_rmpf)
118 #endif /* LOG_REF_MPF_LEAVE */
123 #define tnum_mpf ((uint_t)(tmax_mpfid - TMIN_MPFID + 1))
124 #define tnum_smpf ((uint_t)(tmax_smpfid - TMIN_MPFID + 1))
127 * 固定長メモリプールIDから固定長メモリプール管理ブロックを取り出すた
130 #define INDEX_MPF(mpfid) ((uint_t)((mpfid) - TMIN_MPFID))
131 #define get_mpfcb(mpfid) (&(mpfcb_table[INDEX_MPF(mpfid)]))
136 #define INDEX_NULL (~0U) /* 空きブロックリストの最後 */
137 #define INDEX_ALLOC (~1U) /* 割当て済みのブロック */
139 #ifdef TOPPERS_mpfini
142 * 使用していない固定長メモリプール管理ブロックのリスト
150 initialize_mempfix(void)
156 for (p_mpfcb = mpfcb_table, i = 0; i < tnum_smpf; p_mpfcb++, i++) {
157 queue_initialize(&(p_mpfcb->wait_queue));
158 p_mpfcb->p_mpfinib = &(mpfinib_table[i]);
159 p_mpfcb->fblkcnt = p_mpfcb->p_mpfinib->blkcnt;
160 p_mpfcb->unused = 0U;
161 p_mpfcb->freelist = INDEX_NULL;
163 queue_initialize(&free_mpfcb);
164 for (j = 0; i < tnum_mpf; p_mpfcb++, i++, j++) {
165 p_mpfinib = &(ampfinib_table[j]);
166 p_mpfinib->mpfatr = TA_NOEXS;
167 p_mpfcb->p_mpfinib = ((const MPFINIB *) p_mpfinib);
168 queue_insert_prev(&free_mpfcb, &(p_mpfcb->wait_queue));
172 #endif /* TOPPERS_mpfini */
177 #ifdef TOPPERS_mpfget
180 get_mpf_block(MPFCB *p_mpfcb, void **p_blk)
184 if (p_mpfcb->freelist != INDEX_NULL) {
185 blkidx = p_mpfcb->freelist;
186 p_mpfcb->freelist = (p_mpfcb->p_mpfinib->p_mpfmb + blkidx)->next;
189 blkidx = p_mpfcb->unused;
192 *p_blk = (void *)((char *)(p_mpfcb->p_mpfinib->mpf)
193 + p_mpfcb->p_mpfinib->blksz * blkidx);
195 (p_mpfcb->p_mpfinib->p_mpfmb + blkidx)->next = INDEX_ALLOC;
198 #endif /* TOPPERS_mpfget */
203 #ifdef TOPPERS_acre_mpf
206 acre_mpf(const T_CMPF *pk_cmpf)
215 LOG_ACRE_MPF_ENTER(pk_cmpf);
217 CHECK_RSATR(pk_cmpf->mpfatr, TA_TPRI|TA_MPRI);
218 CHECK_PAR(pk_cmpf->blkcnt != 0);
219 CHECK_PAR(pk_cmpf->blksz != 0);
220 CHECK_ALIGN_MPF(pk_cmpf->mpf);
221 CHECK_ALIGN_MB(pk_cmpf->mpfmb);
222 mpfatr = pk_cmpf->mpfatr;
224 p_mpfmb = pk_cmpf->mpfmb;
227 if (queue_empty(&free_mpfcb)) {
232 mpf = kernel_malloc(pk_cmpf->blkcnt * ROUND_MPF_T(pk_cmpf->blksz));
233 mpfatr |= TA_MEMALLOC;
239 if (p_mpfmb == NULL) {
240 p_mpfmb = kernel_malloc(sizeof(MPFMB) * pk_cmpf->blkcnt);
241 mpfatr |= TA_MBALLOC;
243 if (p_mpfmb == NULL) {
244 if ((mpfatr & TA_MEMALLOC) != 0U) {
250 p_mpfcb = ((MPFCB *) queue_delete_next(&free_mpfcb));
251 p_mpfinib = (MPFINIB *)(p_mpfcb->p_mpfinib);
252 p_mpfinib->mpfatr = mpfatr;
253 p_mpfinib->blkcnt = pk_cmpf->blkcnt;
254 p_mpfinib->blksz = ROUND_MPF_T(pk_cmpf->blksz);
255 p_mpfinib->mpf = mpf;
256 p_mpfinib->p_mpfmb = p_mpfmb;
258 queue_initialize(&(p_mpfcb->wait_queue));
259 p_mpfcb->fblkcnt = p_mpfcb->p_mpfinib->blkcnt;
260 p_mpfcb->unused = 0U;
261 p_mpfcb->freelist = INDEX_NULL;
262 ercd = MPFID(p_mpfcb);
269 LOG_ACRE_MPF_LEAVE(ercd);
273 #endif /* TOPPERS_acre_mpf */
278 #ifdef TOPPERS_del_mpf
288 LOG_DEL_MPF_ENTER(mpfid);
291 p_mpfcb = get_mpfcb(mpfid);
294 if (p_mpfcb->p_mpfinib->mpfatr == TA_NOEXS) {
297 else if (MPFID(p_mpfcb) > tmax_smpfid) {
298 dspreq = init_wait_queue(&(p_mpfcb->wait_queue));
299 p_mpfinib = (MPFINIB *)(p_mpfcb->p_mpfinib);
300 if ((p_mpfinib->mpfatr & TA_MEMALLOC) != 0U) {
301 kernel_free(p_mpfinib->mpf);
303 if ((p_mpfinib->mpfatr & TA_MBALLOC) != 0U) {
304 kernel_free(p_mpfinib->p_mpfmb);
306 p_mpfinib->mpfatr = TA_NOEXS;
307 queue_insert_prev(&free_mpfcb, &(p_mpfcb->wait_queue));
319 LOG_DEL_MPF_LEAVE(ercd);
323 #endif /* TOPPERS_del_mpf */
328 #ifdef TOPPERS_get_mpf
331 get_mpf(ID mpfid, void **p_blk)
337 LOG_GET_MPF_ENTER(mpfid, p_blk);
340 p_mpfcb = get_mpfcb(mpfid);
343 if (p_mpfcb->fblkcnt > 0) {
344 get_mpf_block(p_mpfcb, p_blk);
348 p_runtsk->tstat = (TS_WAITING | TS_WAIT_MPF);
349 wobj_make_wait((WOBJCB *) p_mpfcb, (WINFO_WOBJ *) &winfo_mpf);
351 ercd = winfo_mpf.winfo.wercd;
353 *p_blk = winfo_mpf.blk;
359 LOG_GET_MPF_LEAVE(ercd, *p_blk);
363 #endif /* TOPPERS_get_mpf */
366 * 固定長メモリブロックの獲得(ポーリング)
368 #ifdef TOPPERS_pget_mpf
371 pget_mpf(ID mpfid, void **p_blk)
376 LOG_PGET_MPF_ENTER(mpfid, p_blk);
379 p_mpfcb = get_mpfcb(mpfid);
382 if (p_mpfcb->fblkcnt > 0) {
383 get_mpf_block(p_mpfcb, p_blk);
392 LOG_PGET_MPF_LEAVE(ercd, *p_blk);
396 #endif /* TOPPERS_pget_mpf */
399 * 固定長メモリブロックの獲得(タイムアウトあり)
401 #ifdef TOPPERS_tget_mpf
404 tget_mpf(ID mpfid, void **p_blk, TMO tmout)
411 LOG_TGET_MPF_ENTER(mpfid, p_blk, tmout);
415 p_mpfcb = get_mpfcb(mpfid);
418 if (p_mpfcb->fblkcnt > 0) {
419 get_mpf_block(p_mpfcb, p_blk);
422 else if (tmout == TMO_POL) {
426 p_runtsk->tstat = (TS_WAITING | TS_WAIT_MPF);
427 wobj_make_wait_tmout((WOBJCB *) p_mpfcb, (WINFO_WOBJ *) &winfo_mpf,
430 ercd = winfo_mpf.winfo.wercd;
432 *p_blk = winfo_mpf.blk;
438 LOG_TGET_MPF_LEAVE(ercd, *p_blk);
442 #endif /* TOPPERS_tget_mpf */
447 #ifdef TOPPERS_rel_mpf
450 rel_mpf(ID mpfid, void *blk)
458 LOG_REL_MPF_ENTER(mpfid, blk);
461 p_mpfcb = get_mpfcb(mpfid);
462 CHECK_PAR(p_mpfcb->p_mpfinib->mpf <= blk);
463 blkoffset = ((char *) blk) - (char *)(p_mpfcb->p_mpfinib->mpf);
464 CHECK_PAR(blkoffset % p_mpfcb->p_mpfinib->blksz == 0U);
465 CHECK_PAR(blkoffset / p_mpfcb->p_mpfinib->blksz < p_mpfcb->unused);
466 blkidx = (uint_t)(blkoffset / p_mpfcb->p_mpfinib->blksz);
467 CHECK_PAR((p_mpfcb->p_mpfinib->p_mpfmb + blkidx)->next == INDEX_ALLOC);
470 if (!queue_empty(&(p_mpfcb->wait_queue))) {
471 p_tcb = (TCB *) queue_delete_next(&(p_mpfcb->wait_queue));
472 ((WINFO_MPF *)(p_tcb->p_winfo))->blk = blk;
473 if (wait_complete(p_tcb)) {
480 (p_mpfcb->p_mpfinib->p_mpfmb + blkidx)->next = p_mpfcb->freelist;
481 p_mpfcb->freelist = blkidx;
487 LOG_REL_MPF_LEAVE(ercd);
491 #endif /* TOPPERS_rel_mpf */
496 #ifdef TOPPERS_ini_mpf
505 LOG_INI_MPF_ENTER(mpfid);
508 p_mpfcb = get_mpfcb(mpfid);
511 dspreq = init_wait_queue(&(p_mpfcb->wait_queue));
512 p_mpfcb->fblkcnt = p_mpfcb->p_mpfinib->blkcnt;
513 p_mpfcb->unused = 0U;
514 p_mpfcb->freelist = INDEX_NULL;
522 LOG_INI_MPF_LEAVE(ercd);
526 #endif /* TOPPERS_ini_mpf */
531 #ifdef TOPPERS_ref_mpf
534 ref_mpf(ID mpfid, T_RMPF *pk_rmpf)
539 LOG_REF_MPF_ENTER(mpfid, pk_rmpf);
542 p_mpfcb = get_mpfcb(mpfid);
545 pk_rmpf->wtskid = wait_tskid(&(p_mpfcb->wait_queue));
546 pk_rmpf->fblkcnt = p_mpfcb->fblkcnt;
551 LOG_REF_MPF_LEAVE(ercd, pk_rmpf);
555 #endif /* TOPPERS_ref_mpf */