Lines Matching refs:mem

57 #include "lwip/mem.h"
91 * @param p the mem element to check
108 snprintf(errstr, sizeof(errstr), "detected mem overflow in %s%s", descr1, descr2);
119 snprintf(errstr, sizeof(errstr), "detected mem underflow in %s%s", descr1, descr2);
132 * Initialize the restricted area of a mem element.
169 mem_trim(void *mem, mem_size_t size)
172 return mem;
332 LWIP_ASSERT("MEM_USE_POOLS: mem overflow detected", data == 0xcd);
349 struct mem {
370 #define SIZEOF_STRUCT_MEM LWIP_MEM_ALIGN_SIZE(sizeof(struct mem))
378 /** the heap. we need one struct mem at the end and some room for alignment */
386 static struct mem *ram_end;
421 static struct mem * LWIP_MEM_LFREE_VOLATILE lfree;
432 mem_overflow_init_element(struct mem *mem, mem_size_t user_size)
434 void *p = (u8_t *)mem + SIZEOF_STRUCT_MEM + MEM_SANITY_OFFSET;
435 mem->user_size = user_size;
440 mem_overflow_check_element(struct mem *mem)
442 void *p = (u8_t *)mem + SIZEOF_STRUCT_MEM + MEM_SANITY_OFFSET;
443 mem_overflow_check_raw(p, mem->user_size, "heap", "");
446 #define mem_overflow_init_element(mem, size)
447 #define mem_overflow_check_element(mem)
450 static struct mem *
453 return (struct mem *)(void *)&ram[ptr];
457 mem_to_ptr(void *mem)
459 return (mem_size_t)((u8_t *)mem - ram);
465 * one empty struct mem pointing to another empty struct mem.
467 * @param mem this points to a struct mem which just has been freed
474 plug_holes(struct mem *mem)
476 struct mem *nmem;
477 struct mem *pmem;
479 LWIP_ASSERT("plug_holes: mem >= ram", (u8_t *)mem >= ram);
480 LWIP_ASSERT("plug_holes: mem < ram_end", (u8_t *)mem < (u8_t *)ram_end);
481 LWIP_ASSERT("plug_holes: mem->used == 0", mem->used == 0);
484 LWIP_ASSERT("plug_holes: mem->next <= MEM_SIZE_ALIGNED", mem->next <= MEM_SIZE_ALIGNED);
486 nmem = ptr_to_mem(mem->next);
487 if (mem != nmem && nmem->used == 0 && (u8_t *)nmem != (u8_t *)ram_end) {
488 /* if mem->next is unused and not end of ram, combine mem and mem->next */
490 lfree = mem;
492 mem->next = nmem->next;
494 ptr_to_mem(nmem->next)->prev = mem_to_ptr(mem);
499 pmem = ptr_to_mem(mem->prev);
500 if (pmem != mem && pmem->used == 0) {
501 /* if mem->prev is unused, combine mem and mem->prev */
502 if (lfree == mem) {
505 pmem->next = mem->next;
506 if (mem->next != MEM_SIZE_ALIGNED) {
507 ptr_to_mem(mem->next)->prev = mem_to_ptr(pmem);
518 struct mem *mem;
526 mem = (struct mem *)(void *)ram;
527 mem->next = MEM_SIZE_ALIGNED;
528 mem->prev = 0;
529 mem->used = 0;
538 lfree = (struct mem *)(void *)ram;
547 /* Check if a struct mem is correctly linked.
551 mem_link_valid(struct mem *mem)
553 struct mem *nmem, *pmem;
555 rmem_idx = mem_to_ptr(mem);
556 nmem = ptr_to_mem(mem->next);
557 pmem = ptr_to_mem(mem->prev);
558 if ((mem->next > MEM_SIZE_ALIGNED) || (mem->prev > MEM_SIZE_ALIGNED) ||
559 ((mem->prev != rmem_idx) && (pmem->next != rmem_idx)) ||
570 struct mem *mem;
574 mem = (struct mem *)ram;
575 LWIP_ASSERT("heap element used valid", (mem->used == 0) || (mem->used == 1));
576 last_used = mem->used;
577 LWIP_ASSERT("heap element prev ptr valid", mem->prev == 0);
578 LWIP_ASSERT("heap element next ptr valid", mem->next <= MEM_SIZE_ALIGNED);
579 LWIP_ASSERT("heap element next ptr aligned", LWIP_MEM_ALIGN(ptr_to_mem(mem->next) == ptr_to_mem(mem->next)));
582 for (mem = ptr_to_mem(mem->next);
583 ((u8_t *)mem > ram) && (mem < ram_end);
584 mem = ptr_to_mem(mem->next)) {
585 LWIP_ASSERT("heap element aligned", LWIP_MEM_ALIGN(mem) == mem);
586 LWIP_ASSERT("heap element prev ptr valid", mem->prev <= MEM_SIZE_ALIGNED);
587 LWIP_ASSERT("heap element next ptr valid", mem->next <= MEM_SIZE_ALIGNED);
588 LWIP_ASSERT("heap element prev ptr aligned", LWIP_MEM_ALIGN(ptr_to_mem(mem->prev) == ptr_to_mem(mem->prev)));
589 LWIP_ASSERT("heap element next ptr aligned", LWIP_MEM_ALIGN(ptr_to_mem(mem->next) == ptr_to_mem(mem->next)));
593 LWIP_ASSERT("heap element unused?", mem->used == 1);
595 LWIP_ASSERT("heap element unused member", (mem->used == 0) || (mem->used == 1));
598 LWIP_ASSERT("heap element link valid", mem_link_valid(mem));
601 last_used = mem->used;
603 LWIP_ASSERT("heap end ptr sanity", mem == ptr_to_mem(MEM_SIZE_ALIGNED));
604 LWIP_ASSERT("heap element used valid", mem->used == 1);
605 LWIP_ASSERT("heap element prev ptr valid", mem->prev == MEM_SIZE_ALIGNED);
606 LWIP_ASSERT("heap element next ptr valid", mem->next == MEM_SIZE_ALIGNED);
611 * Put a struct mem back on the heap
613 * @param rmem is the data portion of a struct mem as returned by a previous
619 struct mem *mem;
629 /* protect mem stats from concurrent access */
634 /* Get the corresponding struct mem: */
636 mem = (struct mem *)(void *)((u8_t *)rmem - (SIZEOF_STRUCT_MEM + MEM_SANITY_OFFSET));
638 if ((u8_t *)mem < ram || (u8_t *)rmem + MIN_SIZE_ALIGNED > (u8_t *)ram_end) {
641 /* protect mem stats from concurrent access */
646 mem_overflow_check_element(mem);
650 /* mem has to be in a used state */
651 if (!mem->used) {
655 /* protect mem stats from concurrent access */
660 if (!mem_link_valid(mem)) {
664 /* protect mem stats from concurrent access */
669 /* mem is now unused. */
670 mem->used = 0;
672 if (mem < lfree) {
674 lfree = mem;
677 MEM_STATS_DEC_USED(used, mem->next - (mem_size_t)(((u8_t *)mem - ram)));
680 plug_holes(mem);
703 struct mem *mem, *mem2;
726 /* protect mem stats from concurrent access */
730 /* Get the corresponding struct mem ... */
732 mem = (struct mem *)(void *)((u8_t *)rmem - (SIZEOF_STRUCT_MEM + MEM_SANITY_OFFSET));
734 mem_overflow_check_element(mem);
737 ptr = mem_to_ptr(mem);
739 size = (mem_size_t)((mem_size_t)(mem->next - ptr) - (SIZEOF_STRUCT_MEM + MEM_SANITY_OVERHEAD));
753 mem2 = ptr_to_mem(mem->next);
757 LWIP_ASSERT("invalid next ptr", mem->next != MEM_SIZE_ALIGNED);
760 /* create new struct mem which is moved directly after the shrinked mem */
769 /* link it back to mem */
771 /* link mem to it */
772 mem->next = ptr2;
782 /* Next struct is used but there's room for another struct mem with
784 * Old size ('size') must be big enough to contain at least 'newsize' plus a struct mem
787 * region that couldn't hold data, but when mem->next gets freed,
790 LWIP_ASSERT("invalid next ptr", mem->next != MEM_SIZE_ALIGNED);
796 mem2->next = mem->next;
798 mem->next = ptr2;
803 /* the original mem->next is used, so no need to plug holes! */
806 next struct mem is used but size between mem and mem2 is not big enough
807 to create another struct mem
812 mem_overflow_init_element(mem, new_size);
834 struct mem *mem, *mem2;
872 mem = ptr_to_mem(ptr);
880 could have altered our current struct mem. */
886 if ((!mem->used) &&
887 (mem->next - (ptr + SIZEOF_STRUCT_MEM)) >= size) {
888 /* mem is not used and at least perfect fit is possible:
889 * mem->next - (ptr + SIZEOF_STRUCT_MEM) gives us the 'user data size' of mem */
891 if (mem->next - (ptr + SIZEOF_STRUCT_MEM) >= (size + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED)) {
892 /* (in addition to the above, we test if another struct mem (SIZEOF_STRUCT_MEM) containing
893 * at least MIN_SIZE_ALIGNED of data also fits in the 'user data space' of 'mem')
896 * mem->next - (ptr + (2*SIZEOF_STRUCT_MEM)) == size,
897 * struct mem would fit in but no data between mem2 and mem2->next
899 * region that couldn't hold data, but when mem->next gets freed,
907 mem2->next = mem->next;
909 /* and insert it between mem and mem->next */
910 mem->next = ptr2;
911 mem->used = 1;
918 /* (a mem2 struct does no fit into the user data space of mem and mem->next will always
922 * also can't move mem->next directly behind mem, since mem->next
925 mem->used = 1;
926 MEM_STATS_INC_USED(used, mem->next - mem_to_ptr(mem));
931 if (mem == lfree) {
932 struct mem *cur = lfree;
933 /* Find next free block after mem and update lowest free pointer */
942 could have altered our current struct mem or lfree. */
954 (mem_ptr_t)mem + SIZEOF_STRUCT_MEM + size <= (mem_ptr_t)ram_end);
956 ((mem_ptr_t)mem + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT == 0);
958 (((mem_ptr_t)mem) & (MEM_ALIGNMENT - 1)) == 0);
961 mem_overflow_init_element(mem, size_in);
964 return (u8_t *)mem + SIZEOF_STRUCT_MEM + MEM_SANITY_OFFSET;