source: azure_iot_hub_f767zi/trunk/asp_baseplatform/syssvc/malloc.c@ 457

Last change on this file since 457 was 457, checked in by coas-nagasima, 4 years ago

ファイルを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 9.3 KB
Line 
1/*
2 * TOPPERS/ASP/FMP Kernel
3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Advanced Standard Profile Kernel
5 *
6 * Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
7 * Graduate School of Information Science, Nagoya Univ., JAPAN
8 * Copyright (C) 2015-2020 by TOPPERS PROJECT Educational Working Group.
9 *
10 * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
11 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
12 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
13 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
14 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
15 * スコード中に含まれていること.
16 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
17 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
18 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
19 * の無保証規定を掲載すること.
20 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
21 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
22 * と.
23 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
24 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
25 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
26 * 報告すること.
27 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
28 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
29 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
30 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
31 * 免責すること.
32 *
33 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
34 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
35 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
36 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
37 * の責任を負わない.
38 *
39 * @(#) $Id$
40 */
41/*
42 *
43 * メモリアロケーション機能
44 *
45 */
46#include <kernel.h>
47#include <t_syslog.h>
48#include <stdlib.h>
49#include <string.h>
50#include "kernel_cfg.h"
51
52#ifndef CACHE_LINE_SIZE
53#define CACHE_LINE_SIZE 32 /* default cacle line size */
54#endif
55
56#if defined(TLSF_SEM) /* TLSF */
57#include "tlsf.h"
58
59/*
60 * TLSF2.4.6には、アロケート、フリーを何度も繰り返すと
61 * アロケート領域の先頭8バイトが破壊される問題がある.
62 * TLSF側の修正は品質保証できないため、malloc/free関数で
63 * 対応を行う.
64 */
65#define TLSF_PTR_AREA_SIZE 8
66
67static void *memory_pool;
68
69/*
70 * プール初期化
71 */
72void
73heap_init(intptr_t exinf)
74{
75 intptr_t *param = (intptr_t *)exinf;
76 uint32_t *p;
77 int i, size;
78 memory_pool = (void*)param[0];
79 p = (uint32_t *)param[0];
80 size = param[1] / sizeof(uint32_t);
81 for(i = 0 ; i < size ; i++)
82 *p++ = 0;
83 init_memory_pool(param[1], (void*)memory_pool);
84}
85
86/*
87 * MALLOC
88 */
89void *
90__wrap__malloc_r(struct _reent *reent, size_t __size)
91{
92 void *mempool, *addr;
93 mempool = (void *)memory_pool;
94 if(mempool == NULL)
95 return NULL;
96 wai_sem(TLSF_SEM);
97 addr = (void*)malloc_ex(__size+TLSF_PTR_AREA_SIZE, mempool);
98 sig_sem(TLSF_SEM);
99 if(addr != NULL)
100 return addr+TLSF_PTR_AREA_SIZE;
101 else
102 return addr;
103}
104
105/*
106 * CALLOC
107 */
108void *
109__wrap__calloc_r(struct _reent *reent, size_t __nmemb, size_t __size)
110{
111 void *mempool, *addr;
112 mempool = (void *)memory_pool;
113 if(mempool == NULL)
114 return NULL;
115 wai_sem(TLSF_SEM);
116 addr = (void*)malloc_ex((__nmemb * __size)+TLSF_PTR_AREA_SIZE, mempool);
117 sig_sem(TLSF_SEM);
118 if(addr != NULL){
119 memset(addr+TLSF_PTR_AREA_SIZE, 0, __nmemb * __size);
120 return addr+TLSF_PTR_AREA_SIZE;
121 }
122 else
123 return addr;
124}
125
126/*
127 * REALLOC
128 */
129void *__wrap__realloc_r(struct _reent *reent, void *ptr, size_t __size)
130{
131 void *mempool, *addr;
132 mempool = (void *)memory_pool;
133 if(mempool == NULL)
134 return NULL;
135 wai_sem(TLSF_SEM);
136 addr = (void*)realloc_ex(ptr, __size+TLSF_PTR_AREA_SIZE, mempool);
137 sig_sem(TLSF_SEM);
138 if(addr != NULL)
139 return addr+TLSF_PTR_AREA_SIZE;
140 else
141 return addr;
142}
143
144/*
145 * FREE
146 */
147void
148__wrap__free_r(struct _reent *reent, void *ptr)
149{
150 void *mempool = memory_pool;
151 if(ptr == NULL)
152 return;
153 if(mempool != NULL){
154 wai_sem(TLSF_SEM);
155 free_ex(ptr-TLSF_PTR_AREA_SIZE, mempool);
156 sig_sem(TLSF_SEM);
157 }
158}
159
160#elif(LOCAL_MALLOC) /* LOCAL MALLOC */
161
162typedef struct _LMAP LMAP_t;
163struct _LMAP {
164 unsigned long lsize; /* メモリサイズ */
165 LMAP_t * laddr; /* メモリスタートポインタ */
166};
167
168static LMAP_t lmap;
169
170/*
171 * ローカルアロケータ初期化
172 */
173void
174heap_init(intptr_t exinf)
175{
176 intptr_t *param = (intptr_t *)exinf;
177 LMAP_t *plmap;
178
179 plmap = (LMAP_t *)param[0];
180 plmap->lsize = (unsigned long)param[1];
181 plmap->laddr = NULL;
182 lmap.lsize = plmap->lsize;
183 lmap.laddr = plmap;
184}
185
186/*
187 * MALLOC
188 */
189void *
190__wrap__malloc_r(struct _reent *reent, size_t __size)
191{
192 LMAP_t *ph = &lmap;
193 LMAP_t *p;
194
195 __size = (__size+3+sizeof(unsigned int)) & ~3;
196 if(__size < sizeof(LMAP_t))
197 __size = sizeof(LMAP_t);
198
199 loc_cpu();
200 while((p = ph->laddr) != 0){
201 if(p->lsize >= __size && p->lsize < (__size+sizeof(LMAP_t))){
202 ph->laddr = p->laddr;
203 unl_cpu();
204 return (void *)(&p->laddr);
205 }
206 else if(p->lsize >= (__size+sizeof(LMAP_t))){
207 LMAP_t *pw = (LMAP_t *)((char *)p+__size);
208 pw->lsize = p->lsize-__size;
209 pw->laddr = p->laddr;
210 ph->laddr = pw;
211 p->lsize = __size;
212 unl_cpu();
213 return (void *)(&p->laddr);
214 }
215 ph = p;
216 }
217 unl_cpu();
218 return NULL;
219}
220
221/*
222 * CALLOC
223 */
224void *
225__wrap__calloc_r(struct _reent *reent, size_t __nmemb, size_t __size)
226{
227 return __wrap__malloc_r(reent, __nmemb * __size);
228}
229
230/*
231 * FREE
232 */
233void
234__wrap__free_r(struct _reent *reent, void *ptr)
235{
236 LMAP_t *ph = &lmap;
237 LMAP_t *p;
238 char *t, *pf;
239
240 if(ptr == NULL)
241 return;
242 p = (LMAP_t *)((char *)ptr-sizeof(unsigned long));
243 t = (char *)p+p->lsize;
244 loc_cpu();
245 for(;;){
246 if(ph->laddr == NULL){ /* 空きメモリなし */
247 p->laddr = NULL;
248 ph->laddr = p;
249 break;
250 }
251 else if(t == (char *)ph->laddr){
252 p->lsize += (ph->laddr)->lsize;
253 p->laddr = (ph->laddr)->laddr;
254 ph->laddr = p;
255 break;
256 }
257 else if(t < (char *)ph->laddr){
258 p->laddr = ph->laddr;
259 ph->laddr = p;
260 break;
261 }
262 ph = ph->laddr;
263 pf = (char *)ph+ph->lsize;
264 if(pf > (char *)p){ /* 領域オーバーラップ */
265 unl_cpu();
266 syslog_0(LOG_EMERG, "free:FATAL:irrguler free memory !");
267 return;
268 }
269 else if(pf == (char *)p){
270 ph->lsize += p->lsize;
271 if(t > (char *)ph->laddr){ /* 領域オーバーラップ */
272 unl_cpu();
273 syslog_0(LOG_EMERG, "free:FATAL:irrguler free memory !");
274 return;
275 }
276 else if(t == (char *)ph->laddr){
277 ph->lsize += (ph->laddr)->lsize;
278 ph->laddr = (ph->laddr)->laddr;
279 }
280 break;
281 }
282 }
283 unl_cpu();
284}
285
286#else /* LIBC MALLOC */
287#include <kernel_impl.h>
288
289static uintptr_t *heap_param;
290static int malloc_lock_count;
291
292/*
293 * LIBCアロケータ初期化
294 */
295void
296heap_init(intptr_t exinf)
297{
298 heap_param = (uintptr_t *)exinf;
299 malloc_lock_count = 0;
300}
301
302void
303__malloc_lock(void * reent)
304{
305 malloc_lock_count++;
306 if (malloc_lock_count == 1){
307 ER ret;
308 if (sense_context())
309 ret = iloc_cpu();
310 else
311 ret = loc_cpu();
312 if (ret != E_OK)
313 syslog_1(LOG_ERROR, "__malloc_unlock: count[%d] loc_cpu", malloc_lock_count);
314 }
315}
316
317void
318__malloc_unlock(void * reent)
319{
320 malloc_lock_count--;
321 if (malloc_lock_count == 0){
322 ER ret;
323 if (sense_context())
324 ret = iunl_cpu();
325 else
326 ret = unl_cpu();
327 if (ret != E_OK)
328 syslog_1(LOG_ERROR, "__malloc_unlock: count[%d] unl_cpu error !", malloc_lock_count);
329 }
330}
331
332void *
333_sbrk(int incr)
334{
335 static char *heap_end = NULL;
336 char *prev_heap_end;
337
338 if(incr < 0 || incr > heap_param[1]){
339 syslog_2(LOG_ERROR, "_sbrk: incr[%d] parameter error ! %d", incr, malloc_lock_count);
340 return (void *)-1;
341 }
342
343 if(heap_end == NULL)
344 heap_end = (char *)heap_param[0];
345
346 prev_heap_end = heap_end;
347 heap_end += incr;
348
349 if(heap_end < (char *)(heap_param[0]+heap_param[1]))
350 return (void *) prev_heap_end;
351 else{
352 heap_end = prev_heap_end;
353 syslog_2(LOG_ERROR, "_sbrk: incr[%d] allocation error ! %d", incr, malloc_lock_count);
354 return (void *)-1;
355 }
356}
357
358#endif
359
360/*
361 * CACHE ALINE MALLOC
362 */
363void *
364malloc_cache(uint32_t len)
365{
366 void * addr = malloc(len+CACHE_LINE_SIZE);
367 uint32_t *p;
368 intptr_t uaddr;
369
370 if(addr == NULL)
371 return addr;
372 p = addr;
373 uaddr = (intptr_t)addr;
374 if((uaddr & (CACHE_LINE_SIZE-1)) != 0)
375 uaddr &= ~(CACHE_LINE_SIZE-1);
376 uaddr += CACHE_LINE_SIZE;
377 p = (uint32_t *)uaddr;
378 *(p-1) = (intptr_t)addr;
379 return p;
380}
381
382/*
383 * CACHE ALINE FREE
384 */
385void
386free_cache(void *addr)
387{
388 intptr_t *p = addr;
389
390 if(addr == NULL)
391 return;
392 addr = (void*)(*(p-1));
393 free(addr);
394}
395
Note: See TracBrowser for help on using the repository browser.