MeterLogger
Macros | Typedefs | Functions
mem.h File Reference
#include "lwip/opt.h"
Include dependency graph for mem.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define MEM_SIZE_F   U16_F
 
#define LWIP_MEM_ALIGN_SIZE(size)   (((size) + MEM_ALIGNMENT - 1) & ~(MEM_ALIGNMENT-1))
 
#define LWIP_MEM_ALIGN_BUFFER(size)   (((size) + MEM_ALIGNMENT - 1))
 
#define LWIP_MEM_ALIGN(addr)   ((void *)(((mem_ptr_t)(addr) + MEM_ALIGNMENT - 1) & ~(mem_ptr_t)(MEM_ALIGNMENT-1)))
 

Typedefs

typedef u16_t mem_size_t
 

Functions

void mem_init (void) ICACHE_FLASH_ATTR
 
void * mem_trim (void *mem, mem_size_t size) ICACHE_FLASH_ATTR
 
void * mem_malloc (mem_size_t size) ICACHE_FLASH_ATTR
 
void * mem_calloc (mem_size_t count, mem_size_t size) ICACHE_FLASH_ATTR
 
void mem_free (void *mem) ICACHE_FLASH_ATTR
 

Macro Definition Documentation

◆ LWIP_MEM_ALIGN

#define LWIP_MEM_ALIGN (   addr)    ((void *)(((mem_ptr_t)(addr) + MEM_ALIGNMENT - 1) & ~(mem_ptr_t)(MEM_ALIGNMENT-1)))

Align a memory pointer to the alignment defined by MEM_ALIGNMENT so that ADDR % MEM_ALIGNMENT == 0

Definition at line 159 of file mem.h.

Referenced by mem_init(), memp_init(), and pbuf_alloc().

◆ LWIP_MEM_ALIGN_BUFFER

#define LWIP_MEM_ALIGN_BUFFER (   size)    (((size) + MEM_ALIGNMENT - 1))

Calculate safe memory size for an aligned buffer when using an unaligned type as storage. This includes a safety-margin on (MEM_ALIGNMENT - 1) at the start (e.g. if buffer is u8_t[] and actual data will be u32_t*)

Definition at line 152 of file mem.h.

◆ LWIP_MEM_ALIGN_SIZE

#define LWIP_MEM_ALIGN_SIZE (   size)    (((size) + MEM_ALIGNMENT - 1) & ~(MEM_ALIGNMENT-1))

Calculate memory size for an aligned buffer - returns the next highest multiple of MEM_ALIGNMENT (e.g. LWIP_MEM_ALIGN_SIZE(3) and LWIP_MEM_ALIGN_SIZE(4) will both yield 4 for MEM_ALIGNMENT == 4).

Definition at line 144 of file mem.h.

Referenced by mem_malloc(), mem_trim(), and pbuf_alloc().

◆ MEM_SIZE_F

#define MEM_SIZE_F   U16_F

Definition at line 120 of file mem.h.

Typedef Documentation

◆ mem_size_t

typedef u16_t mem_size_t

Definition at line 119 of file mem.h.

Function Documentation

◆ mem_calloc()

void* mem_calloc ( mem_size_t  count,
mem_size_t  size 
)

Contiguously allocates enough space for count objects that are size bytes of memory each and returns a pointer to the allocated memory.

The allocated memory is filled with bytes of value zero.

Parameters
countnumber of objects to allocate
sizesize of the objects to allocate
Returns
pointer to allocated memory / NULL pointer if there is an error

Definition at line 631 of file mem.c.

References mem_malloc(), and os_memset.

632 {
633  void *p;
634 
635  /* allocate 'count' objects of size 'size' */
636  p = mem_malloc(count * size);
637  if (p) {
638  /* zero the memory */
639  os_memset(p, 0, count * size);
640  }
641  return p;
642 }
#define os_memset
Definition: osapi.h:38
void * mem_malloc(mem_size_t size)
Definition: mem.c:493
Here is the call graph for this function:

◆ mem_free()

void mem_free ( void *  rmem)

Put a struct mem back on the heap

Parameters
rmemis the data portion of a struct mem as returned by a previous call to mem_malloc()

Definition at line 310 of file mem.c.

References LWIP_ASSERT, LWIP_DBG_LEVEL_SERIOUS, LWIP_DBG_LEVEL_SEVERE, LWIP_DBG_TRACE, LWIP_DEBUGF, LWIP_MEM_FREE_DECL_PROTECT, LWIP_MEM_FREE_PROTECT, LWIP_MEM_FREE_UNPROTECT, MEM_ALIGNMENT, MEM_DEBUG, MEM_STATS_DEC_USED, MEM_STATS_INC, mem::next, NULL, plug_holes(), SIZEOF_STRUCT_MEM, SYS_ARCH_DECL_PROTECT, SYS_ARCH_PROTECT, SYS_ARCH_UNPROTECT, and mem::used.

Referenced by mem_free_callback(), and pbuf_free().

311 {
312  struct mem *mem;
314 
315  if (rmem == NULL) {
316  LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("mem_free(p == NULL) was called.\n"));
317  return;
318  }
319  LWIP_ASSERT("mem_free: sanity check alignment", (((mem_ptr_t)rmem) & (MEM_ALIGNMENT-1)) == 0);
320 
321  LWIP_ASSERT("mem_free: legal memory", (u8_t *)rmem >= (u8_t *)ram &&
322  (u8_t *)rmem < (u8_t *)ram_end);
323 
324  if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) {
326  LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("mem_free: illegal memory\n"));
327  /* protect mem stats from concurrent access */
328  SYS_ARCH_PROTECT(lev);
329  MEM_STATS_INC(illegal);
330  SYS_ARCH_UNPROTECT(lev);
331  return;
332  }
333  /* protect the heap from concurrent access */
335  /* Get the corresponding struct mem ... */
336  mem = (struct mem *)(void *)((u8_t *)rmem - SIZEOF_STRUCT_MEM);
337  /* ... which has to be in a used state ... */
338  LWIP_ASSERT("mem_free: mem->used", mem->used);
339  /* ... and is now unused. */
340  mem->used = 0;
341 
342  if (mem < lfree) {
343  /* the newly freed struct is now the lowest */
344  lfree = mem;
345  }
346 
347  MEM_STATS_DEC_USED(used, mem->next - (mem_size_t)(((u8_t *)mem - ram)));
348 
349  /* finally, see if prev or next are free also */
350  plug_holes(mem);
351 #if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
352  mem_free_count = 1;
353 #endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
355 }
static void ICACHE_FLASH_ATTR plug_holes(struct mem *mem)
Definition: mem.c:235
#define LWIP_MEM_FREE_DECL_PROTECT()
Definition: mem.c:212
#define SIZEOF_STRUCT_MEM
Definition: mem.c:173
u16_t mem_size_t
Definition: mem.h:119
#define MEM_STATS_INC(x)
Definition: stats.h:239
#define NULL
Definition: def.h:47
#define LWIP_DBG_TRACE
Definition: debug.h:56
#define MEM_ALIGNMENT
Definition: opt.h:124
static struct mem * ram_end
Definition: mem.c:190
#define LWIP_DBG_LEVEL_SEVERE
Definition: debug.h:47
#define SYS_ARCH_DECL_PROTECT(x)
Definition: cc.h:86
#define LWIP_MEM_FREE_PROTECT()
Definition: mem.c:213
static u8_t * ram
Definition: mem.c:188
u8_t used
Definition: mem.c:161
#define LWIP_DEBUGF(debug, message)
Definition: debug.h:94
#define LWIP_DBG_LEVEL_SERIOUS
Definition: debug.h:46
unsigned long mem_ptr_t
Definition: cc.h:58
static struct mem * lfree
Definition: mem.c:192
#define SYS_ARCH_PROTECT(x)
Definition: cc.h:87
unsigned char u8_t
Definition: cc.h:52
#define LWIP_ASSERT(message, assertion)
Definition: debug.h:65
Definition: mem.c:155
#define MEM_STATS_DEC_USED(x, y)
Definition: stats.h:241
#define MEM_DEBUG
Definition: opt.h:1896
#define SYS_ARCH_UNPROTECT(x)
Definition: cc.h:88
#define LWIP_MEM_FREE_UNPROTECT()
Definition: mem.c:214
mem_size_t next
Definition: mem.c:157
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mem_init()

void mem_init ( void  )

Zero the heap and initialize start, end and lowest-free

Definition at line 273 of file mem.c.

References ERR_OK, LWIP_ASSERT, LWIP_MEM_ALIGN, LWIP_RAM_HEAP_POINTER, MEM_ALIGNMENT, MEM_SIZE_ALIGNED, MEM_STATS_AVAIL, mem::next, mem::prev, ram, SIZEOF_STRUCT_MEM, sys_mutex_new(), and mem::used.

Referenced by lwip_init().

274 {
275  struct mem *mem;
276 
277  LWIP_ASSERT("Sanity check alignment",
278  (SIZEOF_STRUCT_MEM & (MEM_ALIGNMENT-1)) == 0);
279 
280  /* align the heap */
282  /* initialize the start of the heap */
283  mem = (struct mem *)(void *)ram;
284  mem->next = MEM_SIZE_ALIGNED;
285  mem->prev = 0;
286  mem->used = 0;
287  /* initialize the end of the heap */
288  ram_end = (struct mem *)(void *)&ram[MEM_SIZE_ALIGNED];
289  ram_end->used = 1;
292 
293  /* initialize the lowest-free pointer to the start of the heap */
294  lfree = (struct mem *)(void *)ram;
295 
297 
298  if(sys_mutex_new(&mem_mutex) != ERR_OK) {
299  LWIP_ASSERT("failed to create mem_mutex", 0);
300  }
301 }
err_t sys_mutex_new(sys_mutex_t *mutex)
#define SIZEOF_STRUCT_MEM
Definition: mem.c:173
mem_size_t prev
Definition: mem.c:159
#define MEM_ALIGNMENT
Definition: opt.h:124
static struct mem * ram_end
Definition: mem.c:190
#define MEM_STATS_AVAIL(x, y)
Definition: stats.h:238
static u8_t * ram
Definition: mem.c:188
u8_t used
Definition: mem.c:161
#define ERR_OK
Definition: err.h:52
static struct mem * lfree
Definition: mem.c:192
unsigned char u8_t
Definition: cc.h:52
#define LWIP_ASSERT(message, assertion)
Definition: debug.h:65
#define LWIP_RAM_HEAP_POINTER
Definition: mem.c:184
Definition: mem.c:155
#define MEM_SIZE_ALIGNED
Definition: mem.c:174
#define LWIP_MEM_ALIGN(addr)
Definition: mem.h:159
mem_size_t next
Definition: mem.c:157
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mem_malloc()

void* mem_malloc ( mem_size_t  size)

Adam's mem_malloc() plus solution for bug #17922 Allocate a block of memory with a minimum of 'size' bytes.

Parameters
sizeis the minimum size of the requested block in bytes.
Returns
pointer to allocated memory or NULL if no free memory was found.

Note that the returned value will always be aligned (as defined by MEM_ALIGNMENT).

Definition at line 493 of file mem.c.

References LWIP_ASSERT, LWIP_DBG_LEVEL_SERIOUS, LWIP_DEBUGF, LWIP_MEM_ALIGN_SIZE, LWIP_MEM_ALLOC_DECL_PROTECT, LWIP_MEM_ALLOC_PROTECT, LWIP_MEM_ALLOC_UNPROTECT, MEM_ALIGNMENT, MEM_DEBUG, MEM_SIZE_ALIGNED, MEM_STATS_INC, MEM_STATS_INC_USED, MIN_SIZE_ALIGNED, mem::next, NULL, mem::prev, S16_F, SIZEOF_STRUCT_MEM, sys_mutex_lock(), sys_mutex_unlock(), and mem::used.

Referenced by mem_calloc(), and pbuf_alloc().

494 {
495  mem_size_t ptr, ptr2;
496  struct mem *mem, *mem2;
497 #if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
498  u8_t local_mem_free_count = 0;
499 #endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
501 
502  if (size == 0) {
503  return NULL;
504  }
505 
506  /* Expand the size of the allocated memory region so that we can
507  adjust for alignment. */
508  size = LWIP_MEM_ALIGN_SIZE(size);
509 
510  if(size < MIN_SIZE_ALIGNED) {
511  /* every data block must be at least MIN_SIZE_ALIGNED long */
512  size = MIN_SIZE_ALIGNED;
513  }
514 
515  if (size > MEM_SIZE_ALIGNED) {
516  return NULL;
517  }
518 
519  /* protect the heap from concurrent access */
520  sys_mutex_lock(&mem_mutex);
522 #if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
523  /* run as long as a mem_free disturbed mem_malloc */
524  do {
525  local_mem_free_count = 0;
526 #endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
527 
528  /* Scan through the heap searching for a free block that is big enough,
529  * beginning with the lowest free block.
530  */
531  for (ptr = (mem_size_t)((u8_t *)lfree - ram); ptr < MEM_SIZE_ALIGNED - size;
532  ptr = ((struct mem *)(void *)&ram[ptr])->next) {
533  mem = (struct mem *)(void *)&ram[ptr];
534 #if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
535  mem_free_count = 0;
537  /* allow mem_free to run */
539  if (mem_free_count != 0) {
540  local_mem_free_count = mem_free_count;
541  }
542  mem_free_count = 0;
543 #endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
544 
545  if ((!mem->used) &&
546  (mem->next - (ptr + SIZEOF_STRUCT_MEM)) >= size) {
547  /* mem is not used and at least perfect fit is possible:
548  * mem->next - (ptr + SIZEOF_STRUCT_MEM) gives us the 'user data size' of mem */
549 
550  if (mem->next - (ptr + SIZEOF_STRUCT_MEM) >= (size + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED)) {
551  /* (in addition to the above, we test if another struct mem (SIZEOF_STRUCT_MEM) containing
552  * at least MIN_SIZE_ALIGNED of data also fits in the 'user data space' of 'mem')
553  * -> split large block, create empty remainder,
554  * remainder must be large enough to contain MIN_SIZE_ALIGNED data: if
555  * mem->next - (ptr + (2*SIZEOF_STRUCT_MEM)) == size,
556  * struct mem would fit in but no data between mem2 and mem2->next
557  * @todo we could leave out MIN_SIZE_ALIGNED. We would create an empty
558  * region that couldn't hold data, but when mem->next gets freed,
559  * the 2 regions would be combined, resulting in more free memory
560  */
561  ptr2 = ptr + SIZEOF_STRUCT_MEM + size;
562  /* create mem2 struct */
563  mem2 = (struct mem *)(void *)&ram[ptr2];
564  mem2->used = 0;
565  mem2->next = mem->next;
566  mem2->prev = ptr;
567  /* and insert it between mem and mem->next */
568  mem->next = ptr2;
569  mem->used = 1;
570 
571  if (mem2->next != MEM_SIZE_ALIGNED) {
572  ((struct mem *)(void *)&ram[mem2->next])->prev = ptr2;
573  }
575  } else {
576  /* (a mem2 struct does no fit into the user data space of mem and mem->next will always
577  * be used at this point: if not we have 2 unused structs in a row, plug_holes should have
578  * take care of this).
579  * -> near fit or excact fit: do not split, no mem2 creation
580  * also can't move mem->next directly behind mem, since mem->next
581  * will always be used at this point!
582  */
583  mem->used = 1;
584  MEM_STATS_INC_USED(used, mem->next - (mem_size_t)((u8_t *)mem - ram));
585  }
586 
587  if (mem == lfree) {
588  /* Find next free block after mem and update lowest free pointer */
589  while (lfree->used && lfree != ram_end) {
591  /* prevent high interrupt latency... */
593  lfree = (struct mem *)(void *)&ram[lfree->next];
594  }
595  LWIP_ASSERT("mem_malloc: !lfree->used", ((lfree == ram_end) || (!lfree->used)));
596  }
598  sys_mutex_unlock(&mem_mutex);
599  LWIP_ASSERT("mem_malloc: allocated memory not above ram_end.",
600  (mem_ptr_t)mem + SIZEOF_STRUCT_MEM + size <= (mem_ptr_t)ram_end);
601  LWIP_ASSERT("mem_malloc: allocated memory properly aligned.",
602  ((mem_ptr_t)mem + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT == 0);
603  LWIP_ASSERT("mem_malloc: sanity check alignment",
604  (((mem_ptr_t)mem) & (MEM_ALIGNMENT-1)) == 0);
605 
606  return (u8_t *)mem + SIZEOF_STRUCT_MEM;
607  }
608  }
609 #if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
610  /* if we got interrupted by a mem_free, try again */
611  } while(local_mem_free_count != 0);
612 #endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
613  LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("mem_malloc: could not allocate %"S16_F" bytes\n", (s16_t)size));
614  MEM_STATS_INC(err);
616  sys_mutex_unlock(&mem_mutex);
617  return NULL;
618 }
#define LWIP_MEM_ALLOC_PROTECT()
Definition: mem.c:217
signed short s16_t
Definition: cc.h:55
#define SIZEOF_STRUCT_MEM
Definition: mem.c:173
u16_t mem_size_t
Definition: mem.h:119
void sys_mutex_unlock(sys_mutex_t *mutex)
#define MEM_STATS_INC(x)
Definition: stats.h:239
#define NULL
Definition: def.h:47
mem_size_t prev
Definition: mem.c:159
void sys_mutex_lock(sys_mutex_t *mutex)
#define MEM_ALIGNMENT
Definition: opt.h:124
static struct mem * ram_end
Definition: mem.c:190
static u8_t * ram
Definition: mem.c:188
u8_t used
Definition: mem.c:161
#define LWIP_MEM_ALIGN_SIZE(size)
Definition: mem.h:144
#define LWIP_DEBUGF(debug, message)
Definition: debug.h:94
#define LWIP_MEM_ALLOC_DECL_PROTECT()
Definition: mem.c:216
#define LWIP_DBG_LEVEL_SERIOUS
Definition: debug.h:46
unsigned long mem_ptr_t
Definition: cc.h:58
static struct mem * lfree
Definition: mem.c:192
#define S16_F
Definition: cc.h:60
unsigned char u8_t
Definition: cc.h:52
#define LWIP_ASSERT(message, assertion)
Definition: debug.h:65
Definition: mem.c:155
#define MEM_STATS_INC_USED(x, y)
Definition: stats.h:240
#define MEM_DEBUG
Definition: opt.h:1896
#define MEM_SIZE_ALIGNED
Definition: mem.c:174
#define LWIP_MEM_ALLOC_UNPROTECT()
Definition: mem.c:218
#define MIN_SIZE_ALIGNED
Definition: mem.c:172
mem_size_t next
Definition: mem.c:157
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mem_trim()

void* mem_trim ( void *  rmem,
mem_size_t  newsize 
)

Shrink memory returned by mem_malloc().

Parameters
rmempointer to memory allocated by mem_malloc the is to be shrinked
newsizerequired size after shrinking (needs to be smaller than or equal to the previous size)
Returns
for compatibility reasons: is always == rmem, at the moment or NULL if newsize is > old size, in which case rmem is NOT touched or freed!

Definition at line 368 of file mem.c.

References LWIP_ASSERT, LWIP_DBG_LEVEL_SEVERE, LWIP_DEBUGF, LWIP_MEM_ALIGN_SIZE, LWIP_MEM_FREE_DECL_PROTECT, LWIP_MEM_FREE_PROTECT, LWIP_MEM_FREE_UNPROTECT, MEM_DEBUG, MEM_SIZE_ALIGNED, MEM_STATS_DEC_USED, MEM_STATS_INC, MIN_SIZE_ALIGNED, mem::next, NULL, mem::prev, ram, SIZEOF_STRUCT_MEM, SYS_ARCH_DECL_PROTECT, SYS_ARCH_PROTECT, SYS_ARCH_UNPROTECT, and mem::used.

Referenced by pbuf_realloc().

369 {
370  mem_size_t size;
371  mem_size_t ptr, ptr2;
372  struct mem *mem, *mem2;
373  /* use the FREE_PROTECT here: it protects with sem OR SYS_ARCH_PROTECT */
375 
376  /* Expand the size of the allocated memory region so that we can
377  adjust for alignment. */
378  newsize = LWIP_MEM_ALIGN_SIZE(newsize);
379 
380  if(newsize < MIN_SIZE_ALIGNED) {
381  /* every data block must be at least MIN_SIZE_ALIGNED long */
382  newsize = MIN_SIZE_ALIGNED;
383  }
384 
385  if (newsize > MEM_SIZE_ALIGNED) {
386  return NULL;
387  }
388 
389  LWIP_ASSERT("mem_trim: legal memory", (u8_t *)rmem >= (u8_t *)ram &&
390  (u8_t *)rmem < (u8_t *)ram_end);
391 
392  if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) {
394  LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("mem_trim: illegal memory\n"));
395  /* protect mem stats from concurrent access */
396  SYS_ARCH_PROTECT(lev);
397  MEM_STATS_INC(illegal);
398  SYS_ARCH_UNPROTECT(lev);
399  return rmem;
400  }
401  /* Get the corresponding struct mem ... */
402  mem = (struct mem *)(void *)((u8_t *)rmem - SIZEOF_STRUCT_MEM);
403  /* ... and its offset pointer */
404  ptr = (mem_size_t)((u8_t *)mem - ram);
405 
406  size = mem->next - ptr - SIZEOF_STRUCT_MEM;
407  LWIP_ASSERT("mem_trim can only shrink memory", newsize <= size);
408  if (newsize > size) {
409  /* not supported */
410  return NULL;
411  }
412  if (newsize == size) {
413  /* No change in size, simply return */
414  return rmem;
415  }
416 
417  /* protect the heap from concurrent access */
419 
420  mem2 = (struct mem *)(void *)&ram[mem->next];
421  if(mem2->used == 0) {
422  /* The next struct is unused, we can simply move it at little */
424  /* remember the old next pointer */
425  next = mem2->next;
426  /* create new struct mem which is moved directly after the shrinked mem */
427  ptr2 = ptr + SIZEOF_STRUCT_MEM + newsize;
428  if (lfree == mem2) {
429  lfree = (struct mem *)(void *)&ram[ptr2];
430  }
431  mem2 = (struct mem *)(void *)&ram[ptr2];
432  mem2->used = 0;
433  /* restore the next pointer */
434  mem2->next = next;
435  /* link it back to mem */
436  mem2->prev = ptr;
437  /* link mem to it */
438  mem->next = ptr2;
439  /* last thing to restore linked list: as we have moved mem2,
440  * let 'mem2->next->prev' point to mem2 again. but only if mem2->next is not
441  * the end of the heap */
442  if (mem2->next != MEM_SIZE_ALIGNED) {
443  ((struct mem *)(void *)&ram[mem2->next])->prev = ptr2;
444  }
445  MEM_STATS_DEC_USED(used, (size - newsize));
446  /* no need to plug holes, we've already done that */
447  } else if (newsize + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED <= size) {
448  /* Next struct is used but there's room for another struct mem with
449  * at least MIN_SIZE_ALIGNED of data.
450  * Old size ('size') must be big enough to contain at least 'newsize' plus a struct mem
451  * ('SIZEOF_STRUCT_MEM') with some data ('MIN_SIZE_ALIGNED').
452  * @todo we could leave out MIN_SIZE_ALIGNED. We would create an empty
453  * region that couldn't hold data, but when mem->next gets freed,
454  * the 2 regions would be combined, resulting in more free memory */
455  ptr2 = ptr + SIZEOF_STRUCT_MEM + newsize;
456  mem2 = (struct mem *)(void *)&ram[ptr2];
457  if (mem2 < lfree) {
458  lfree = mem2;
459  }
460  mem2->used = 0;
461  mem2->next = mem->next;
462  mem2->prev = ptr;
463  mem->next = ptr2;
464  if (mem2->next != MEM_SIZE_ALIGNED) {
465  ((struct mem *)(void *)&ram[mem2->next])->prev = ptr2;
466  }
467  MEM_STATS_DEC_USED(used, (size - newsize));
468  /* the original mem->next is used, so no need to plug holes! */
469  }
470  /* else {
471  next struct mem is used but size between mem and mem2 is not big enough
472  to create another struct mem
473  -> don't do anyhting.
474  -> the remaining space stays unused since it is too small
475  } */
476 #if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
477  mem_free_count = 1;
478 #endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
480  return rmem;
481 }
#define LWIP_MEM_FREE_DECL_PROTECT()
Definition: mem.c:212
#define SIZEOF_STRUCT_MEM
Definition: mem.c:173
u16_t mem_size_t
Definition: mem.h:119
#define MEM_STATS_INC(x)
Definition: stats.h:239
#define NULL
Definition: def.h:47
mem_size_t prev
Definition: mem.c:159
static struct mem * ram_end
Definition: mem.c:190
#define LWIP_DBG_LEVEL_SEVERE
Definition: debug.h:47
#define SYS_ARCH_DECL_PROTECT(x)
Definition: cc.h:86
#define LWIP_MEM_FREE_PROTECT()
Definition: mem.c:213
static u8_t * ram
Definition: mem.c:188
u8_t used
Definition: mem.c:161
#define LWIP_MEM_ALIGN_SIZE(size)
Definition: mem.h:144
#define LWIP_DEBUGF(debug, message)
Definition: debug.h:94
static struct mem * lfree
Definition: mem.c:192
#define SYS_ARCH_PROTECT(x)
Definition: cc.h:87
unsigned char u8_t
Definition: cc.h:52
#define LWIP_ASSERT(message, assertion)
Definition: debug.h:65
Definition: mem.c:155
#define MEM_STATS_DEC_USED(x, y)
Definition: stats.h:241
#define MEM_DEBUG
Definition: opt.h:1896
#define MEM_SIZE_ALIGNED
Definition: mem.c:174
#define SYS_ARCH_UNPROTECT(x)
Definition: cc.h:88
#define MIN_SIZE_ALIGNED
Definition: mem.c:172
#define LWIP_MEM_FREE_UNPROTECT()
Definition: mem.c:214
mem_size_t next
Definition: mem.c:157
Here is the caller graph for this function: