source: azure_iot_hub/trunk/asp3_dcre/kernel/mempfix.c

Last change on this file was 389, checked in by coas-nagasima, 5 years ago

ビルドが通るよう更新

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 13.8 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-2016 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_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, p_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, p_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, p_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 uint_t blkcnt;
214 uint_t blksz;
215 MPF_T *mpf;
216 MPFMB *p_mpfmb;
217 ER ercd;
218
219 LOG_ACRE_MPF_ENTER(pk_cmpf);
220 CHECK_TSKCTX_UNL();
221
222 mpfatr = pk_cmpf->mpfatr;
223 blkcnt = pk_cmpf->blkcnt;
224 blksz = pk_cmpf->blksz;
225 mpf = pk_cmpf->mpf;
226 p_mpfmb = pk_cmpf->mpfmb;
227
228 CHECK_RSATR(mpfatr, TA_TPRI);
229 CHECK_PAR(blkcnt != 0);
230 CHECK_PAR(blksz != 0);
231 if (mpf != NULL) {
232 CHECK_PAR(MPF_ALIGN(mpf));
233 }
234 if (p_mpfmb != NULL) {
235 CHECK_PAR(MB_ALIGN(p_mpfmb));
236 }
237
238 lock_cpu();
239 if (tnum_mpf == 0 || queue_empty(&free_mpfcb)) {
240 ercd = E_NOID;
241 }
242 else {
243 if (mpf == NULL) {
244 mpf = kernel_malloc(ROUND_MPF_T(blksz) * blkcnt);
245 mpfatr |= TA_MEMALLOC;
246 }
247 if (mpf == NULL) {
248 ercd = E_NOMEM;
249 }
250 else {
251 if (p_mpfmb == NULL) {
252 p_mpfmb = kernel_malloc(sizeof(MPFMB) * blkcnt);
253 mpfatr |= TA_MBALLOC;
254 }
255 if (p_mpfmb == NULL) {
256 if (mpf == NULL) {
257 kernel_free(mpf);
258 }
259 ercd = E_NOMEM;
260 }
261 else {
262 p_mpfcb = ((MPFCB *) queue_delete_next(&free_mpfcb));
263 p_mpfinib = (MPFINIB *)(p_mpfcb->p_mpfinib);
264 p_mpfinib->mpfatr = mpfatr;
265 p_mpfinib->blkcnt = blkcnt;
266 p_mpfinib->blksz = ROUND_MPF_T(blksz);
267 p_mpfinib->mpf = mpf;
268 p_mpfinib->p_mpfmb = p_mpfmb;
269
270 queue_initialize(&(p_mpfcb->wait_queue));
271 p_mpfcb->fblkcnt = p_mpfcb->p_mpfinib->blkcnt;
272 p_mpfcb->unused = 0U;
273 p_mpfcb->freelist = INDEX_NULL;
274 ercd = MPFID(p_mpfcb);
275 }
276 }
277 }
278 unlock_cpu();
279
280 error_exit:
281 LOG_ACRE_MPF_LEAVE(ercd);
282 return(ercd);
283}
284
285#endif /* TOPPERS_acre_mpf */
286
287/*
288 * 固定長メモリプールの削除
289 */
290#ifdef TOPPERS_del_mpf
291
292ER
293del_mpf(ID mpfid)
294{
295 MPFCB *p_mpfcb;
296 MPFINIB *p_mpfinib;
297 ER ercd;
298
299 LOG_DEL_MPF_ENTER(mpfid);
300 CHECK_TSKCTX_UNL();
301 CHECK_ID(VALID_MPFID(mpfid));
302 p_mpfcb = get_mpfcb(mpfid);
303
304 lock_cpu();
305 if (p_mpfcb->p_mpfinib->mpfatr == TA_NOEXS) {
306 ercd = E_NOEXS;
307 }
308 else if (mpfid <= tmax_smpfid) {
309 ercd = E_OBJ;
310 }
311 else {
312 init_wait_queue(&(p_mpfcb->wait_queue));
313 p_mpfinib = (MPFINIB *)(p_mpfcb->p_mpfinib);
314 if ((p_mpfinib->mpfatr & TA_MEMALLOC) != 0U) {
315 kernel_free(p_mpfinib->mpf);
316 }
317 if ((p_mpfinib->mpfatr & TA_MBALLOC) != 0U) {
318 kernel_free(p_mpfinib->p_mpfmb);
319 }
320 p_mpfinib->mpfatr = TA_NOEXS;
321 queue_insert_prev(&free_mpfcb, &(p_mpfcb->wait_queue));
322 if (p_runtsk != p_schedtsk) {
323 dispatch();
324 }
325 ercd = E_OK;
326 }
327 unlock_cpu();
328
329 error_exit:
330 LOG_DEL_MPF_LEAVE(ercd);
331 return(ercd);
332}
333
334#endif /* TOPPERS_del_mpf */
335
336/*
337 * 固定長メモリブロックの獲得
338 */
339#ifdef TOPPERS_get_mpf
340
341ER
342get_mpf(ID mpfid, void **p_blk)
343{
344 MPFCB *p_mpfcb;
345 WINFO_MPF winfo_mpf;
346 ER ercd;
347
348 LOG_GET_MPF_ENTER(mpfid, p_blk);
349 CHECK_DISPATCH();
350 CHECK_ID(VALID_MPFID(mpfid));
351 p_mpfcb = get_mpfcb(mpfid);
352
353 lock_cpu_dsp();
354 if (p_mpfcb->p_mpfinib->mpfatr == TA_NOEXS) {
355 ercd = E_NOEXS;
356 }
357 else if (p_runtsk->raster) {
358 ercd = E_RASTER;
359 }
360 else if (p_mpfcb->fblkcnt > 0) {
361 get_mpf_block(p_mpfcb, p_blk);
362 ercd = E_OK;
363 }
364 else {
365 p_runtsk->tstat = TS_WAITING_MPF;
366 wobj_make_wait((WOBJCB *) p_mpfcb, (WINFO_WOBJ *) &winfo_mpf);
367 dispatch();
368 ercd = winfo_mpf.winfo.wercd;
369 if (ercd == E_OK) {
370 *p_blk = winfo_mpf.blk;
371 }
372 }
373 unlock_cpu_dsp();
374
375 error_exit:
376 LOG_GET_MPF_LEAVE(ercd, p_blk);
377 return(ercd);
378}
379
380#endif /* TOPPERS_get_mpf */
381
382/*
383 * 固定長メモリブロックの獲得(ポーリング)
384 */
385#ifdef TOPPERS_pget_mpf
386
387ER
388pget_mpf(ID mpfid, void **p_blk)
389{
390 MPFCB *p_mpfcb;
391 ER ercd;
392
393 LOG_PGET_MPF_ENTER(mpfid, p_blk);
394 CHECK_TSKCTX_UNL();
395 CHECK_ID(VALID_MPFID(mpfid));
396 p_mpfcb = get_mpfcb(mpfid);
397
398 lock_cpu();
399 if (p_mpfcb->p_mpfinib->mpfatr == TA_NOEXS) {
400 ercd = E_NOEXS;
401 }
402 else if (p_mpfcb->fblkcnt > 0) {
403 get_mpf_block(p_mpfcb, p_blk);
404 ercd = E_OK;
405 }
406 else {
407 ercd = E_TMOUT;
408 }
409 unlock_cpu();
410
411 error_exit:
412 LOG_PGET_MPF_LEAVE(ercd, p_blk);
413 return(ercd);
414}
415
416#endif /* TOPPERS_pget_mpf */
417
418/*
419 * 固定長メモリブロックの獲得(タイムアウトあり)
420 */
421#ifdef TOPPERS_tget_mpf
422
423ER
424tget_mpf(ID mpfid, void **p_blk, TMO tmout)
425{
426 MPFCB *p_mpfcb;
427 WINFO_MPF winfo_mpf;
428 TMEVTB tmevtb;
429 ER ercd;
430
431 LOG_TGET_MPF_ENTER(mpfid, p_blk, tmout);
432 CHECK_DISPATCH();
433 CHECK_ID(VALID_MPFID(mpfid));
434 CHECK_PAR(VALID_TMOUT(tmout));
435 p_mpfcb = get_mpfcb(mpfid);
436
437 lock_cpu_dsp();
438 if (p_mpfcb->p_mpfinib->mpfatr == TA_NOEXS) {
439 ercd = E_NOEXS;
440 }
441 else if (p_runtsk->raster) {
442 ercd = E_RASTER;
443 }
444 else if (p_mpfcb->fblkcnt > 0) {
445 get_mpf_block(p_mpfcb, p_blk);
446 ercd = E_OK;
447 }
448 else if (tmout == TMO_POL) {
449 ercd = E_TMOUT;
450 }
451 else {
452 p_runtsk->tstat = TS_WAITING_MPF;
453 wobj_make_wait_tmout((WOBJCB *) p_mpfcb, (WINFO_WOBJ *) &winfo_mpf,
454 &tmevtb, tmout);
455 dispatch();
456 ercd = winfo_mpf.winfo.wercd;
457 if (ercd == E_OK) {
458 *p_blk = winfo_mpf.blk;
459 }
460 }
461 unlock_cpu_dsp();
462
463 error_exit:
464 LOG_TGET_MPF_LEAVE(ercd, p_blk);
465 return(ercd);
466}
467
468#endif /* TOPPERS_tget_mpf */
469
470/*
471 * 固定長メモリブロックの返却
472 */
473#ifdef TOPPERS_rel_mpf
474
475ER
476rel_mpf(ID mpfid, void *blk)
477{
478 MPFCB *p_mpfcb;
479 size_t blkoffset;
480 uint_t blkidx;
481 TCB *p_tcb;
482 ER ercd;
483
484 LOG_REL_MPF_ENTER(mpfid, blk);
485 CHECK_TSKCTX_UNL();
486 CHECK_ID(VALID_MPFID(mpfid));
487 p_mpfcb = get_mpfcb(mpfid);
488
489 lock_cpu();
490 if (p_mpfcb->p_mpfinib->mpfatr == TA_NOEXS) {
491 ercd = E_NOEXS;
492 }
493 else {
494 blkoffset = ((char *) blk) - (char *)(p_mpfcb->p_mpfinib->mpf);
495 blkidx = (uint_t)(blkoffset / p_mpfcb->p_mpfinib->blksz);
496 if (!(p_mpfcb->p_mpfinib->mpf <= blk)
497 || !(blkoffset % p_mpfcb->p_mpfinib->blksz == 0U)
498 || !(blkoffset / p_mpfcb->p_mpfinib->blksz < p_mpfcb->unused)
499 || !((p_mpfcb->p_mpfinib->p_mpfmb + blkidx)->next
500 == INDEX_ALLOC)) {
501 ercd = E_PAR;
502 }
503 else if (!queue_empty(&(p_mpfcb->wait_queue))) {
504 p_tcb = (TCB *) queue_delete_next(&(p_mpfcb->wait_queue));
505 ((WINFO_MPF *)(p_tcb->p_winfo))->blk = blk;
506 wait_complete(p_tcb);
507 if (p_runtsk != p_schedtsk) {
508 dispatch();
509 }
510 ercd = E_OK;
511 }
512 else {
513 p_mpfcb->fblkcnt++;
514 (p_mpfcb->p_mpfinib->p_mpfmb + blkidx)->next = p_mpfcb->freelist;
515 p_mpfcb->freelist = blkidx;
516 ercd = E_OK;
517 }
518 }
519 unlock_cpu();
520
521 error_exit:
522 LOG_REL_MPF_LEAVE(ercd);
523 return(ercd);
524}
525
526#endif /* TOPPERS_rel_mpf */
527
528/*
529 * 固定長メモリプールの再初期化
530 */
531#ifdef TOPPERS_ini_mpf
532
533ER
534ini_mpf(ID mpfid)
535{
536 MPFCB *p_mpfcb;
537 ER ercd;
538
539 LOG_INI_MPF_ENTER(mpfid);
540 CHECK_TSKCTX_UNL();
541 CHECK_ID(VALID_MPFID(mpfid));
542 p_mpfcb = get_mpfcb(mpfid);
543
544 lock_cpu();
545 if (p_mpfcb->p_mpfinib->mpfatr == TA_NOEXS) {
546 ercd = E_NOEXS;
547 }
548 else {
549 init_wait_queue(&(p_mpfcb->wait_queue));
550 p_mpfcb->fblkcnt = p_mpfcb->p_mpfinib->blkcnt;
551 p_mpfcb->unused = 0U;
552 p_mpfcb->freelist = INDEX_NULL;
553 if (p_runtsk != p_schedtsk) {
554 dispatch();
555 }
556 ercd = E_OK;
557 }
558 unlock_cpu();
559
560 error_exit:
561 LOG_INI_MPF_LEAVE(ercd);
562 return(ercd);
563}
564
565#endif /* TOPPERS_ini_mpf */
566
567/*
568 * 固定長メモリプールの状態参照
569 */
570#ifdef TOPPERS_ref_mpf
571
572ER
573ref_mpf(ID mpfid, T_RMPF *pk_rmpf)
574{
575 MPFCB *p_mpfcb;
576 ER ercd;
577
578 LOG_REF_MPF_ENTER(mpfid, pk_rmpf);
579 CHECK_TSKCTX_UNL();
580 CHECK_ID(VALID_MPFID(mpfid));
581 p_mpfcb = get_mpfcb(mpfid);
582
583 lock_cpu();
584 if (p_mpfcb->p_mpfinib->mpfatr == TA_NOEXS) {
585 ercd = E_NOEXS;
586 }
587 else {
588 pk_rmpf->wtskid = wait_tskid(&(p_mpfcb->wait_queue));
589 pk_rmpf->fblkcnt = p_mpfcb->fblkcnt;
590 ercd = E_OK;
591 }
592 unlock_cpu();
593
594 error_exit:
595 LOG_REF_MPF_LEAVE(ercd, pk_rmpf);
596 return(ercd);
597}
598
599#endif /* TOPPERS_ref_mpf */
Note: See TracBrowser for help on using the repository browser.