source: UsbWattMeter/trunk/asp_dcre/kernel/mempfix.c@ 473

Last change on this file since 473 was 167, checked in by coas-nagasima, 8 years ago

MIMEにSJISを設定

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc; charset=SHIFT_JIS
File size: 12.7 KB
Line 
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-2014 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: mempfix.c 167 2016-03-08 11:37:45Z coas-nagasima $
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_ACRE_MPF_ENTER
57#define LOG_ACRE_MPF_ENTER(pk_cmpf)
58#endif /* LOG_ACRE_MPF_ENTER */
59
60#ifndef LOG_ACRE_MPF_LEAVE
61#define LOG_ACRE_MPF_LEAVE(ercd)
62#endif /* LOG_ACRE_MPF_LEAVE */
63
64#ifndef LOG_DEL_MPF_ENTER
65#define LOG_DEL_MPF_ENTER(mpfid)
66#endif /* LOG_DEL_MPF_ENTER */
67
68#ifndef LOG_DEL_MPF_LEAVE
69#define LOG_DEL_MPF_LEAVE(ercd)
70#endif /* LOG_DEL_MPF_LEAVE */
71
72#ifndef LOG_GET_MPF_ENTER
73#define LOG_GET_MPF_ENTER(mpfid, p_blk)
74#endif /* LOG_GET_MPF_ENTER */
75
76#ifndef LOG_GET_MPF_LEAVE
77#define LOG_GET_MPF_LEAVE(ercd, blk)
78#endif /* LOG_GET_MPF_LEAVE */
79
80#ifndef LOG_PGET_MPF_ENTER
81#define LOG_PGET_MPF_ENTER(mpfid, p_blk)
82#endif /* LOG_PGET_MPF_ENTER */
83
84#ifndef LOG_PGET_MPF_LEAVE
85#define LOG_PGET_MPF_LEAVE(ercd, blk)
86#endif /* LOG_PGET_MPF_LEAVE */
87
88#ifndef LOG_TGET_MPF_ENTER
89#define LOG_TGET_MPF_ENTER(mpfid, p_blk, tmout)
90#endif /* LOG_TGET_MPF_ENTER */
91
92#ifndef LOG_TGET_MPF_LEAVE
93#define LOG_TGET_MPF_LEAVE(ercd, blk)
94#endif /* LOG_TGET_MPF_LEAVE */
95
96#ifndef LOG_REL_MPF_ENTER
97#define LOG_REL_MPF_ENTER(mpfid, blk)
98#endif /* LOG_REL_MPF_ENTER */
99
100#ifndef LOG_REL_MPF_LEAVE
101#define LOG_REL_MPF_LEAVE(ercd)
102#endif /* LOG_REL_MPF_LEAVE */
103
104#ifndef LOG_INI_MPF_ENTER
105#define LOG_INI_MPF_ENTER(mpfid)
106#endif /* LOG_INI_MPF_ENTER */
107
108#ifndef LOG_INI_MPF_LEAVE
109#define LOG_INI_MPF_LEAVE(ercd)
110#endif /* LOG_INI_MPF_LEAVE */
111
112#ifndef LOG_REF_MPF_ENTER
113#define LOG_REF_MPF_ENTER(mpfid, pk_rmpf)
114#endif /* LOG_REF_MPF_ENTER */
115
116#ifndef LOG_REF_MPF_LEAVE
117#define LOG_REF_MPF_LEAVE(ercd, pk_rmpf)
118#endif /* LOG_REF_MPF_LEAVE */
119
120/*
121 * 固定長メモリプールの数
122 */
123#define tnum_mpf ((uint_t)(tmax_mpfid - TMIN_MPFID + 1))
124#define tnum_smpf ((uint_t)(tmax_smpfid - TMIN_MPFID + 1))
125
126/*
127 * 固定長メモリプールIDから固定長メモリプール管理ブロックを取り出すた
128 * めのマクロ
129 */
130#define INDEX_MPF(mpfid) ((uint_t)((mpfid) - TMIN_MPFID))
131#define get_mpfcb(mpfid) (&(mpfcb_table[INDEX_MPF(mpfid)]))
132
133/*
134 * 特殊なインデックス値の定義
135 */
136#define INDEX_NULL (~0U) /* 空きブロックリストの最後 */
137#define INDEX_ALLOC (~1U) /* 割当て済みのブロック */
138
139#ifdef TOPPERS_mpfini
140
141/*
142 * 使用していない固定長メモリプール管理ブロックのリスト
143 */
144QUEUE free_mpfcb;
145
146/*
147 * 固定長メモリプール機能の初期化
148 */
149void
150initialize_mempfix(void)
151{
152 uint_t i, j;
153 MPFCB *p_mpfcb;
154 MPFINIB *p_mpfinib;
155
156 for (i = 0; i < tnum_smpf; i++) {
157 p_mpfcb = &(mpfcb_table[i]);
158 queue_initialize(&(p_mpfcb->wait_queue));
159 p_mpfcb->p_mpfinib = &(mpfinib_table[i]);
160 p_mpfcb->fblkcnt = p_mpfcb->p_mpfinib->blkcnt;
161 p_mpfcb->unused = 0U;
162 p_mpfcb->freelist = INDEX_NULL;
163 }
164 queue_initialize(&free_mpfcb);
165 for (j = 0; i < tnum_mpf; i++, j++) {
166 p_mpfcb = &(mpfcb_table[i]);
167 p_mpfinib = &(ampfinib_table[j]);
168 p_mpfinib->mpfatr = TA_NOEXS;
169 p_mpfcb->p_mpfinib = ((const MPFINIB *) p_mpfinib);
170 queue_insert_prev(&free_mpfcb, &(p_mpfcb->wait_queue));
171 }
172}
173
174#endif /* TOPPERS_mpfini */
175
176/*
177 * 固定長メモリプールからブロックを獲得
178 */
179#ifdef TOPPERS_mpfget
180
181void
182get_mpf_block(MPFCB *p_mpfcb, void **p_blk)
183{
184 uint_t blkidx;
185
186 if (p_mpfcb->freelist != INDEX_NULL) {
187 blkidx = p_mpfcb->freelist;
188 p_mpfcb->freelist = (p_mpfcb->p_mpfinib->p_mpfmb + blkidx)->next;
189 }
190 else {
191 blkidx = p_mpfcb->unused;
192 p_mpfcb->unused++;
193 }
194 *p_blk = (void *)((char *)(p_mpfcb->p_mpfinib->mpf)
195 + p_mpfcb->p_mpfinib->blksz * blkidx);
196 p_mpfcb->fblkcnt--;
197 (p_mpfcb->p_mpfinib->p_mpfmb + blkidx)->next = INDEX_ALLOC;
198}
199
200#endif /* TOPPERS_mpfget */
201
202/*
203 * 固定長メモリプールの生成
204 */
205#ifdef TOPPERS_acre_mpf
206
207ER_UINT
208acre_mpf(const T_CMPF *pk_cmpf)
209{
210 MPFCB *p_mpfcb;
211 MPFINIB *p_mpfinib;
212 ATR mpfatr;
213 void *mpf;
214 MPFMB *p_mpfmb;
215 ER ercd;
216
217 LOG_ACRE_MPF_ENTER(pk_cmpf);
218 CHECK_TSKCTX_UNL();
219 CHECK_RSATR(pk_cmpf->mpfatr, TA_TPRI);
220 CHECK_PAR(pk_cmpf->blkcnt != 0);
221 CHECK_PAR(pk_cmpf->blksz != 0);
222 if (pk_cmpf->mpf != NULL) {
223 CHECK_ALIGN_MPF(pk_cmpf->mpf);
224 }
225 if (pk_cmpf->mpfmb != NULL) {
226 CHECK_ALIGN_MB(pk_cmpf->mpfmb);
227 }
228 mpfatr = pk_cmpf->mpfatr;
229 mpf = pk_cmpf->mpf;
230 p_mpfmb = pk_cmpf->mpfmb;
231
232 t_lock_cpu();
233 if (tnum_mpf == 0 || queue_empty(&free_mpfcb)) {
234 ercd = E_NOID;
235 }
236 else {
237 if (mpf == NULL) {
238 mpf = kernel_malloc(ROUND_MPF_T(pk_cmpf->blksz) * pk_cmpf->blkcnt);
239 mpfatr |= TA_MEMALLOC;
240 }
241 if (mpf == NULL) {
242 ercd = E_NOMEM;
243 }
244 else {
245 if (p_mpfmb == NULL) {
246 p_mpfmb = kernel_malloc(sizeof(MPFMB) * pk_cmpf->blkcnt);
247 mpfatr |= TA_MBALLOC;
248 }
249 if (p_mpfmb == NULL) {
250 if (pk_cmpf->mpf == NULL) {
251 kernel_free(mpf);
252 }
253 ercd = E_NOMEM;
254 }
255 else {
256 p_mpfcb = ((MPFCB *) queue_delete_next(&free_mpfcb));
257 p_mpfinib = (MPFINIB *)(p_mpfcb->p_mpfinib);
258 p_mpfinib->mpfatr = mpfatr;
259 p_mpfinib->blkcnt = pk_cmpf->blkcnt;
260 p_mpfinib->blksz = ROUND_MPF_T(pk_cmpf->blksz);
261 p_mpfinib->mpf = mpf;
262 p_mpfinib->p_mpfmb = p_mpfmb;
263
264 queue_initialize(&(p_mpfcb->wait_queue));
265 p_mpfcb->fblkcnt = p_mpfcb->p_mpfinib->blkcnt;
266 p_mpfcb->unused = 0U;
267 p_mpfcb->freelist = INDEX_NULL;
268 ercd = MPFID(p_mpfcb);
269 }
270 }
271 }
272 t_unlock_cpu();
273
274 error_exit:
275 LOG_ACRE_MPF_LEAVE(ercd);
276 return(ercd);
277}
278
279#endif /* TOPPERS_acre_mpf */
280
281/*
282 * 固定長メモリプールの削除
283 */
284#ifdef TOPPERS_del_mpf
285
286ER
287del_mpf(ID mpfid)
288{
289 MPFCB *p_mpfcb;
290 MPFINIB *p_mpfinib;
291 bool_t dspreq;
292 ER ercd;
293
294 LOG_DEL_MPF_ENTER(mpfid);
295 CHECK_TSKCTX_UNL();
296 CHECK_MPFID(mpfid);
297 p_mpfcb = get_mpfcb(mpfid);
298
299 t_lock_cpu();
300 if (p_mpfcb->p_mpfinib->mpfatr == TA_NOEXS) {
301 ercd = E_NOEXS;
302 }
303 else if (MPFID(p_mpfcb) > tmax_smpfid) {
304 dspreq = init_wait_queue(&(p_mpfcb->wait_queue));
305 p_mpfinib = (MPFINIB *)(p_mpfcb->p_mpfinib);
306 if ((p_mpfinib->mpfatr & TA_MEMALLOC) != 0U) {
307 kernel_free(p_mpfinib->mpf);
308 }
309 if ((p_mpfinib->mpfatr & TA_MBALLOC) != 0U) {
310 kernel_free(p_mpfinib->p_mpfmb);
311 }
312 p_mpfinib->mpfatr = TA_NOEXS;
313 queue_insert_prev(&free_mpfcb, &(p_mpfcb->wait_queue));
314 if (dspreq) {
315 dispatch();
316 }
317 ercd = E_OK;
318 }
319 else {
320 ercd = E_OBJ;
321 }
322 t_unlock_cpu();
323
324 error_exit:
325 LOG_DEL_MPF_LEAVE(ercd);
326 return(ercd);
327}
328
329#endif /* TOPPERS_del_mpf */
330
331/*
332 * 固定長メモリブロックの獲得
333 */
334#ifdef TOPPERS_get_mpf
335
336ER
337get_mpf(ID mpfid, void **p_blk)
338{
339 MPFCB *p_mpfcb;
340 WINFO_MPF winfo_mpf;
341 ER ercd;
342
343 LOG_GET_MPF_ENTER(mpfid, p_blk);
344 CHECK_DISPATCH();
345 CHECK_MPFID(mpfid);
346 p_mpfcb = get_mpfcb(mpfid);
347
348 t_lock_cpu();
349 if (p_mpfcb->p_mpfinib->mpfatr == TA_NOEXS) {
350 ercd = E_NOEXS;
351 }
352 else if (p_mpfcb->fblkcnt > 0) {
353 get_mpf_block(p_mpfcb, p_blk);
354 ercd = E_OK;
355 }
356 else {
357 p_runtsk->tstat = (TS_WAITING | TS_WAIT_MPF);
358 wobj_make_wait((WOBJCB *) p_mpfcb, (WINFO_WOBJ *) &winfo_mpf);
359 dispatch();
360 ercd = winfo_mpf.winfo.wercd;
361 if (ercd == E_OK) {
362 *p_blk = winfo_mpf.blk;
363 }
364 }
365 t_unlock_cpu();
366
367 error_exit:
368 LOG_GET_MPF_LEAVE(ercd, *p_blk);
369 return(ercd);
370}
371
372#endif /* TOPPERS_get_mpf */
373
374/*
375 * 固定長メモリブロックの獲得(ポーリング)
376 */
377#ifdef TOPPERS_pget_mpf
378
379ER
380pget_mpf(ID mpfid, void **p_blk)
381{
382 MPFCB *p_mpfcb;
383 ER ercd;
384
385 LOG_PGET_MPF_ENTER(mpfid, p_blk);
386 CHECK_TSKCTX_UNL();
387 CHECK_MPFID(mpfid);
388 p_mpfcb = get_mpfcb(mpfid);
389
390 t_lock_cpu();
391 if (p_mpfcb->p_mpfinib->mpfatr == TA_NOEXS) {
392 ercd = E_NOEXS;
393 }
394 else if (p_mpfcb->fblkcnt > 0) {
395 get_mpf_block(p_mpfcb, p_blk);
396 ercd = E_OK;
397 }
398 else {
399 ercd = E_TMOUT;
400 }
401 t_unlock_cpu();
402
403 error_exit:
404 LOG_PGET_MPF_LEAVE(ercd, *p_blk);
405 return(ercd);
406}
407
408#endif /* TOPPERS_pget_mpf */
409
410/*
411 * 固定長メモリブロックの獲得(タイムアウトあり)
412 */
413#ifdef TOPPERS_tget_mpf
414
415ER
416tget_mpf(ID mpfid, void **p_blk, TMO tmout)
417{
418 MPFCB *p_mpfcb;
419 WINFO_MPF winfo_mpf;
420 TMEVTB tmevtb;
421 ER ercd;
422
423 LOG_TGET_MPF_ENTER(mpfid, p_blk, tmout);
424 CHECK_DISPATCH();
425 CHECK_MPFID(mpfid);
426 CHECK_TMOUT(tmout);
427 p_mpfcb = get_mpfcb(mpfid);
428
429 t_lock_cpu();
430 if (p_mpfcb->p_mpfinib->mpfatr == TA_NOEXS) {
431 ercd = E_NOEXS;
432 }
433 else if (p_mpfcb->fblkcnt > 0) {
434 get_mpf_block(p_mpfcb, p_blk);
435 ercd = E_OK;
436 }
437 else if (tmout == TMO_POL) {
438 ercd = E_TMOUT;
439 }
440 else {
441 p_runtsk->tstat = (TS_WAITING | TS_WAIT_MPF);
442 wobj_make_wait_tmout((WOBJCB *) p_mpfcb, (WINFO_WOBJ *) &winfo_mpf,
443 &tmevtb, tmout);
444 dispatch();
445 ercd = winfo_mpf.winfo.wercd;
446 if (ercd == E_OK) {
447 *p_blk = winfo_mpf.blk;
448 }
449 }
450 t_unlock_cpu();
451
452 error_exit:
453 LOG_TGET_MPF_LEAVE(ercd, *p_blk);
454 return(ercd);
455}
456
457#endif /* TOPPERS_tget_mpf */
458
459/*
460 * 固定長メモリブロックの返却
461 */
462#ifdef TOPPERS_rel_mpf
463
464ER
465rel_mpf(ID mpfid, void *blk)
466{
467 MPFCB *p_mpfcb;
468 SIZE blkoffset;
469 uint_t blkidx;
470 TCB *p_tcb;
471 ER ercd;
472
473 LOG_REL_MPF_ENTER(mpfid, blk);
474 CHECK_TSKCTX_UNL();
475 CHECK_MPFID(mpfid);
476 p_mpfcb = get_mpfcb(mpfid);
477
478 t_lock_cpu();
479 if (p_mpfcb->p_mpfinib->mpfatr == TA_NOEXS) {
480 ercd = E_NOEXS;
481 }
482 else {
483 blkoffset = ((char *) blk) - (char *)(p_mpfcb->p_mpfinib->mpf);
484 blkidx = (uint_t)(blkoffset / p_mpfcb->p_mpfinib->blksz);
485 if (!(p_mpfcb->p_mpfinib->mpf <= blk)
486 || !(blkoffset % p_mpfcb->p_mpfinib->blksz == 0U)
487 || !(blkoffset / p_mpfcb->p_mpfinib->blksz < p_mpfcb->unused)
488 || !((p_mpfcb->p_mpfinib->p_mpfmb + blkidx)->next
489 == INDEX_ALLOC)) {
490 ercd = E_PAR;
491 }
492 else if (!queue_empty(&(p_mpfcb->wait_queue))) {
493 p_tcb = (TCB *) queue_delete_next(&(p_mpfcb->wait_queue));
494 ((WINFO_MPF *)(p_tcb->p_winfo))->blk = blk;
495 if (wait_complete(p_tcb)) {
496 dispatch();
497 }
498 ercd = E_OK;
499 }
500 else {
501 p_mpfcb->fblkcnt++;
502 (p_mpfcb->p_mpfinib->p_mpfmb + blkidx)->next = p_mpfcb->freelist;
503 p_mpfcb->freelist = blkidx;
504 ercd = E_OK;
505 }
506 }
507 t_unlock_cpu();
508
509 error_exit:
510 LOG_REL_MPF_LEAVE(ercd);
511 return(ercd);
512}
513
514#endif /* TOPPERS_rel_mpf */
515
516/*
517 * 固定長メモリプールの再初期化
518 */
519#ifdef TOPPERS_ini_mpf
520
521ER
522ini_mpf(ID mpfid)
523{
524 MPFCB *p_mpfcb;
525 bool_t dspreq;
526 ER ercd;
527
528 LOG_INI_MPF_ENTER(mpfid);
529 CHECK_TSKCTX_UNL();
530 CHECK_MPFID(mpfid);
531 p_mpfcb = get_mpfcb(mpfid);
532
533 t_lock_cpu();
534 if (p_mpfcb->p_mpfinib->mpfatr == TA_NOEXS) {
535 ercd = E_NOEXS;
536 }
537 else {
538 dspreq = init_wait_queue(&(p_mpfcb->wait_queue));
539 p_mpfcb->fblkcnt = p_mpfcb->p_mpfinib->blkcnt;
540 p_mpfcb->unused = 0U;
541 p_mpfcb->freelist = INDEX_NULL;
542 if (dspreq) {
543 dispatch();
544 }
545 ercd = E_OK;
546 }
547 t_unlock_cpu();
548
549 error_exit:
550 LOG_INI_MPF_LEAVE(ercd);
551 return(ercd);
552}
553
554#endif /* TOPPERS_ini_mpf */
555
556/*
557 * 固定長メモリプールの状態参照
558 */
559#ifdef TOPPERS_ref_mpf
560
561ER
562ref_mpf(ID mpfid, T_RMPF *pk_rmpf)
563{
564 MPFCB *p_mpfcb;
565 ER ercd;
566
567 LOG_REF_MPF_ENTER(mpfid, pk_rmpf);
568 CHECK_TSKCTX_UNL();
569 CHECK_MPFID(mpfid);
570 p_mpfcb = get_mpfcb(mpfid);
571
572 t_lock_cpu();
573 if (p_mpfcb->p_mpfinib->mpfatr == TA_NOEXS) {
574 ercd = E_NOEXS;
575 }
576 else {
577 pk_rmpf->wtskid = wait_tskid(&(p_mpfcb->wait_queue));
578 pk_rmpf->fblkcnt = p_mpfcb->fblkcnt;
579 ercd = E_OK;
580 }
581 t_unlock_cpu();
582
583 error_exit:
584 LOG_REF_MPF_LEAVE(ercd, pk_rmpf);
585 return(ercd);
586}
587
588#endif /* TOPPERS_ref_mpf */
Note: See TracBrowser for help on using the repository browser.