1 |
|
/** @file |
2 |
|
* |
3 |
|
* Dynamic memory manager |
4 |
|
* |
5 |
|
*/ |
6 |
|
|
7 |
/* |
/* |
8 |
* Copyright (c) 2001-2003 Swedish Institute of Computer Science. |
* Copyright (c) 2001-2003 Swedish Institute of Computer Science. |
9 |
* All rights reserved. |
* All rights reserved. |
36 |
* |
* |
37 |
*/ |
*/ |
38 |
|
|
|
/*-----------------------------------------------------------------------------------*/ |
|
|
/* mem.c |
|
|
* |
|
|
* Memory manager. |
|
|
* |
|
|
*/ |
|
|
/*-----------------------------------------------------------------------------------*/ |
|
39 |
|
|
40 |
#include "lwip/arch.h" |
#include "lwip/arch.h" |
41 |
#include "lwip/opt.h" |
#include "lwip/opt.h" |
73 |
|
|
74 |
static sys_sem_t mem_sem; |
static sys_sem_t mem_sem; |
75 |
|
|
|
/*-----------------------------------------------------------------------------------*/ |
|
76 |
static void |
static void |
77 |
plug_holes(struct mem *mem) |
plug_holes(struct mem *mem) |
78 |
{ |
{ |
106 |
} |
} |
107 |
|
|
108 |
} |
} |
|
/*-----------------------------------------------------------------------------------*/ |
|
109 |
void |
void |
110 |
mem_init(void) |
mem_init(void) |
111 |
{ |
{ |
129 |
lwip_stats.mem.avail = MEM_SIZE; |
lwip_stats.mem.avail = MEM_SIZE; |
130 |
#endif /* MEM_STATS */ |
#endif /* MEM_STATS */ |
131 |
} |
} |
|
/*-----------------------------------------------------------------------------------*/ |
|
132 |
void |
void |
133 |
mem_free(void *rmem) |
mem_free(void *rmem) |
134 |
{ |
{ |
135 |
struct mem *mem; |
struct mem *mem; |
136 |
|
|
137 |
if(rmem == NULL) { |
if (rmem == NULL) { |
138 |
|
DEBUGF(MEM_DEBUG | DBG_TRACE | 2, ("mem_free(p == NULL) was called.\n")); |
139 |
return; |
return; |
140 |
} |
} |
141 |
|
|
142 |
sys_sem_wait(mem_sem); |
sys_sem_wait(mem_sem); |
143 |
|
|
144 |
LWIP_ASSERT("mem_free: legal memory", (u8_t *)rmem >= (u8_t *)ram && |
LWIP_ASSERT("mem_free: legal memory", (u8_t *)rmem >= (u8_t *)ram && |
145 |
(u8_t *)rmem < (u8_t *)ram_end); |
(u8_t *)rmem < (u8_t *)ram_end); |
146 |
|
|
147 |
|
if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) { |
|
if((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) { |
|
148 |
DEBUGF(MEM_DEBUG | 3, ("mem_free: illegal memory\n")); |
DEBUGF(MEM_DEBUG | 3, ("mem_free: illegal memory\n")); |
149 |
#ifdef MEM_STATS |
#ifdef MEM_STATS |
150 |
++lwip_stats.mem.err; |
++lwip_stats.mem.err; |
158 |
|
|
159 |
mem->used = 0; |
mem->used = 0; |
160 |
|
|
161 |
if(mem < lfree) { |
if (mem < lfree) { |
162 |
lfree = mem; |
lfree = mem; |
163 |
} |
} |
164 |
|
|
169 |
plug_holes(mem); |
plug_holes(mem); |
170 |
sys_sem_signal(mem_sem); |
sys_sem_signal(mem_sem); |
171 |
} |
} |
|
/*-----------------------------------------------------------------------------------*/ |
|
172 |
void * |
void * |
173 |
mem_reallocm(void *rmem, mem_size_t newsize) |
mem_reallocm(void *rmem, mem_size_t newsize) |
174 |
{ |
{ |
175 |
void *nmem; |
void *nmem; |
176 |
nmem = mem_malloc(newsize); |
nmem = mem_malloc(newsize); |
177 |
if(nmem == NULL) { |
if (nmem == NULL) { |
178 |
return mem_realloc(rmem, newsize); |
return mem_realloc(rmem, newsize); |
179 |
} |
} |
180 |
memcpy(nmem, rmem, newsize); |
memcpy(nmem, rmem, newsize); |
191 |
|
|
192 |
/* Expand the size of the allocated memory region so that we can |
/* Expand the size of the allocated memory region so that we can |
193 |
adjust for alignment. */ |
adjust for alignment. */ |
194 |
if((newsize % MEM_ALIGNMENT) != 0) { |
if ((newsize % MEM_ALIGNMENT) != 0) { |
195 |
newsize += MEM_ALIGNMENT - ((newsize + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT); |
newsize += MEM_ALIGNMENT - ((newsize + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT); |
196 |
} |
} |
197 |
|
|
198 |
if(newsize > MEM_SIZE) { |
if (newsize > MEM_SIZE) { |
199 |
return NULL; |
return NULL; |
200 |
} |
} |
201 |
|
|
204 |
LWIP_ASSERT("mem_realloc: legal memory", (u8_t *)rmem >= (u8_t *)ram && |
LWIP_ASSERT("mem_realloc: legal memory", (u8_t *)rmem >= (u8_t *)ram && |
205 |
(u8_t *)rmem < (u8_t *)ram_end); |
(u8_t *)rmem < (u8_t *)ram_end); |
206 |
|
|
207 |
if((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) { |
if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) { |
208 |
DEBUGF(MEM_DEBUG | 3, ("mem_realloc: illegal memory\n")); |
DEBUGF(MEM_DEBUG | 3, ("mem_realloc: illegal memory\n")); |
209 |
return rmem; |
return rmem; |
210 |
} |
} |
217 |
lwip_stats.mem.used -= (size - newsize); |
lwip_stats.mem.used -= (size - newsize); |
218 |
#endif /* MEM_STATS */ |
#endif /* MEM_STATS */ |
219 |
|
|
220 |
if(newsize + SIZEOF_STRUCT_MEM + MIN_SIZE < size) { |
if (newsize + SIZEOF_STRUCT_MEM + MIN_SIZE < size) { |
221 |
ptr2 = ptr + SIZEOF_STRUCT_MEM + newsize; |
ptr2 = ptr + SIZEOF_STRUCT_MEM + newsize; |
222 |
mem2 = (struct mem *)&ram[ptr2]; |
mem2 = (struct mem *)&ram[ptr2]; |
223 |
mem2->used = 0; |
mem2->used = 0; |
233 |
sys_sem_signal(mem_sem); |
sys_sem_signal(mem_sem); |
234 |
return rmem; |
return rmem; |
235 |
} |
} |
|
/*-----------------------------------------------------------------------------------*/ |
|
236 |
void * |
void * |
237 |
mem_malloc(mem_size_t size) |
mem_malloc(mem_size_t size) |
238 |
{ |
{ |
239 |
mem_size_t ptr, ptr2; |
mem_size_t ptr, ptr2; |
240 |
struct mem *mem, *mem2; |
struct mem *mem, *mem2; |
241 |
|
|
242 |
if(size == 0) { |
if (size == 0) { |
243 |
return NULL; |
return NULL; |
244 |
} |
} |
245 |
|
|
246 |
/* Expand the size of the allocated memory region so that we can |
/* Expand the size of the allocated memory region so that we can |
247 |
adjust for alignment. */ |
adjust for alignment. */ |
248 |
if((size % MEM_ALIGNMENT) != 0) { |
if ((size % MEM_ALIGNMENT) != 0) { |
249 |
size += MEM_ALIGNMENT - ((size + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT); |
size += MEM_ALIGNMENT - ((size + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT); |
250 |
} |
} |
251 |
|
|
252 |
if(size > MEM_SIZE) { |
if (size > MEM_SIZE) { |
253 |
return NULL; |
return NULL; |
254 |
} |
} |
255 |
|
|
256 |
sys_sem_wait(mem_sem); |
sys_sem_wait(mem_sem); |
257 |
|
|
258 |
for(ptr = (u8_t *)lfree - ram; ptr < MEM_SIZE; ptr = ((struct mem *)&ram[ptr])->next) { |
for (ptr = (u8_t *)lfree - ram; ptr < MEM_SIZE; ptr = ((struct mem *)&ram[ptr])->next) { |
259 |
mem = (struct mem *)&ram[ptr]; |
mem = (struct mem *)&ram[ptr]; |
260 |
if(!mem->used && |
if(!mem->used && |
261 |
mem->next - (ptr + SIZEOF_STRUCT_MEM) >= size + SIZEOF_STRUCT_MEM) { |
mem->next - (ptr + SIZEOF_STRUCT_MEM) >= size + SIZEOF_STRUCT_MEM) { |
265 |
mem2->prev = ptr; |
mem2->prev = ptr; |
266 |
mem2->next = mem->next; |
mem2->next = mem->next; |
267 |
mem->next = ptr2; |
mem->next = ptr2; |
268 |
if(mem2->next != MEM_SIZE) { |
if (mem2->next != MEM_SIZE) { |
269 |
((struct mem *)&ram[mem2->next])->prev = ptr2; |
((struct mem *)&ram[mem2->next])->prev = ptr2; |
270 |
} |
} |
271 |
|
|
276 |
/* if(lwip_stats.mem.max < lwip_stats.mem.used) { |
/* if(lwip_stats.mem.max < lwip_stats.mem.used) { |
277 |
lwip_stats.mem.max = lwip_stats.mem.used; |
lwip_stats.mem.max = lwip_stats.mem.used; |
278 |
} */ |
} */ |
279 |
if(lwip_stats.mem.max < ptr2) { |
if (lwip_stats.mem.max < ptr2) { |
280 |
lwip_stats.mem.max = ptr2; |
lwip_stats.mem.max = ptr2; |
281 |
} |
} |
282 |
#endif /* MEM_STATS */ |
#endif /* MEM_STATS */ |
283 |
|
|
284 |
if(mem == lfree) { |
if (mem == lfree) { |
285 |
/* Find next free block after mem */ |
/* Find next free block after mem */ |
286 |
while(lfree->used && lfree != ram_end) { |
while(lfree->used && lfree != ram_end) { |
287 |
lfree = (struct mem *)&ram[lfree->next]; |
lfree = (struct mem *)&ram[lfree->next]; |
303 |
sys_sem_signal(mem_sem); |
sys_sem_signal(mem_sem); |
304 |
return NULL; |
return NULL; |
305 |
} |
} |
|
/*-----------------------------------------------------------------------------------*/ |
|