Lines Matching refs:mem

61 #include "lwip/mem.h"
156 struct mem {
173 #define SIZEOF_STRUCT_MEM LWIP_MEM_ALIGN_SIZE(sizeof(struct mem))
181 /** the heap. we need one struct mem at the end and some room for alignment */
189 static struct mem *ram_end;
191 static struct mem *lfree;
227 * one empty struct mem pointing to another empty struct mem.
229 * @param mem this points to a struct mem which just has been freed
236 plug_holes(struct mem *mem)
238 struct mem *nmem;
239 struct mem *pmem;
241 LWIP_ASSERT("plug_holes: mem >= ram", (u8_t *)mem >= ram);
242 LWIP_ASSERT("plug_holes: mem < ram_end", (u8_t *)mem < (u8_t *)ram_end);
243 LWIP_ASSERT("plug_holes: mem->used == 0", mem->used == 0);
246 LWIP_ASSERT("plug_holes: mem->next <= MEM_SIZE_ALIGNED", mem->next <= MEM_SIZE_ALIGNED);
248 nmem = (struct mem *)(void *)&ram[mem->next];
249 if (mem != nmem && nmem->used == 0 && (u8_t *)nmem != (u8_t *)ram_end) {
250 /* if mem->next is unused and not end of ram, combine mem and mem->next */
252 lfree = mem;
254 mem->next = nmem->next;
255 ((struct mem *)(void *)&ram[nmem->next])->prev = (mem_size_t)((u8_t *)mem - ram);
259 pmem = (struct mem *)(void *)&ram[mem->prev];
260 if (pmem != mem && pmem->used == 0) {
261 /* if mem->prev is unused, combine mem and mem->prev */
262 if (lfree == mem) {
265 pmem->next = mem->next;
266 ((struct mem *)(void *)&ram[mem->next])->prev = (mem_size_t)((u8_t *)pmem - ram);
276 struct mem *mem;
284 mem = (struct mem *)(void *)ram;
285 mem->next = MEM_SIZE_ALIGNED;
286 mem->prev = 0;
287 mem->used = 0;
289 ram_end = (struct mem *)(void *)&ram[MEM_SIZE_ALIGNED];
295 lfree = (struct mem *)(void *)ram;
305 * Put a struct mem back on the heap
307 * @param rmem is the data portion of a struct mem as returned by a previous
313 struct mem *mem;
328 /* protect mem stats from concurrent access */
336 /* Get the corresponding struct mem ... */
337 mem = (struct mem *)(void *)((u8_t *)rmem - SIZEOF_STRUCT_MEM);
339 LWIP_ASSERT("mem_free: mem->used", mem->used);
341 mem->used = 0;
343 if (mem < lfree) {
345 lfree = mem;
348 MEM_STATS_DEC_USED(used, mem->next - (mem_size_t)(((u8_t *)mem - ram)));
351 plug_holes(mem);
373 struct mem *mem, *mem2;
396 /* protect mem stats from concurrent access */
402 /* Get the corresponding struct mem ... */
403 mem = (struct mem *)(void *)((u8_t *)rmem - SIZEOF_STRUCT_MEM);
405 ptr = (mem_size_t)((u8_t *)mem - ram);
407 size = mem->next - ptr - SIZEOF_STRUCT_MEM;
421 mem2 = (struct mem *)(void *)&ram[mem->next];
427 /* create new struct mem which is moved directly after the shrinked mem */
430 lfree = (struct mem *)(void *)&ram[ptr2];
432 mem2 = (struct mem *)(void *)&ram[ptr2];
436 /* link it back to mem */
438 /* link mem to it */
439 mem->next = ptr2;
444 ((struct mem *)(void *)&ram[mem2->next])->prev = ptr2;
449 /* Next struct is used but there's room for another struct mem with
451 * Old size ('size') must be big enough to contain at least 'newsize' plus a struct mem
454 * region that couldn't hold data, but when mem->next gets freed,
457 mem2 = (struct mem *)(void *)&ram[ptr2];
462 mem2->next = mem->next;
464 mem->next = ptr2;
466 ((struct mem *)(void *)&ram[mem2->next])->prev = ptr2;
469 /* the original mem->next is used, so no need to plug holes! */
472 next struct mem is used but size between mem and mem2 is not big enough
473 to create another struct mem
497 struct mem *mem, *mem2;
533 ptr = ((struct mem *)(void *)&ram[ptr])->next) {
534 mem = (struct mem *)(void *)&ram[ptr];
542 could have altered our current struct mem. */
548 if ((!mem->used) &&
549 (mem->next - (ptr + SIZEOF_STRUCT_MEM)) >= size) {
550 /* mem is not used and at least perfect fit is possible:
551 * mem->next - (ptr + SIZEOF_STRUCT_MEM) gives us the 'user data size' of mem */
553 if (mem->next - (ptr + SIZEOF_STRUCT_MEM) >= (size + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED)) {
554 /* (in addition to the above, we test if another struct mem (SIZEOF_STRUCT_MEM) containing
555 * at least MIN_SIZE_ALIGNED of data also fits in the 'user data space' of 'mem')
558 * mem->next - (ptr + (2*SIZEOF_STRUCT_MEM)) == size,
559 * struct mem would fit in but no data between mem2 and mem2->next
561 * region that couldn't hold data, but when mem->next gets freed,
566 mem2 = (struct mem *)(void *)&ram[ptr2];
568 mem2->next = mem->next;
570 /* and insert it between mem and mem->next */
571 mem->next = ptr2;
572 mem->used = 1;
575 ((struct mem *)(void *)&ram[mem2->next])->prev = ptr2;
579 /* (a mem2 struct does no fit into the user data space of mem and mem->next will always
583 * also can't move mem->next directly behind mem, since mem->next
586 mem->used = 1;
587 MEM_STATS_INC_USED(used, mem->next - (mem_size_t)((u8_t *)mem - ram));
592 if (mem == lfree) {
593 struct mem *cur = lfree;
594 /* Find next free block after mem and update lowest free pointer */
603 could have altered our current struct mem or lfree. */
607 cur = (struct mem *)(void *)&ram[cur->next];
615 (mem_ptr_t)mem + SIZEOF_STRUCT_MEM + size <= (mem_ptr_t)ram_end);
617 ((mem_ptr_t)mem + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT == 0);
619 (((mem_ptr_t)mem) & (MEM_ALIGNMENT-1)) == 0);
621 return (u8_t *)mem + SIZEOF_STRUCT_MEM;