⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mem.c

📁 最新的lwip 1.3.0版本在ucos平台上的移植
💻 C
📖 第 1 页 / 共 2 页
字号:
#endif /* MEM_STATS */    sys_sem_signal(mem_sem);    return;  }  /* Get the corresponding struct mem ... */  mem = (struct mem *)((u8_t *)rmem - SIZEOF_STRUCT_MEM);  /* ... which has to be in a used state ... */  LWIP_ASSERT("mem_free: mem->used", mem->used);  /* ... and is now unused. */  mem->used = 0;  if (mem < lfree) {    /* the newly freed struct is now the lowest */    lfree = mem;  }#if MEM_STATS  lwip_stats.mem.used -= mem->next - ((u8_t *)mem - ram);#endif /* MEM_STATS */  /* finally, see if prev or next are free also */  plug_holes(mem);  sys_sem_signal(mem_sem);}/** * In contrast to its name, mem_realloc can only shrink memory, not expand it. * Since the only use (for now) is in pbuf_realloc (which also can only shrink), * this shouldn't be a problem! * * @param rmem pointer to memory allocated by mem_malloc the is to be shrinked * @param newsize required size after shrinking (needs to be smaller than or *                equal to the previous size) * @return for compatibility reasons: is always == rmem, at the moment */void *mem_realloc(void *rmem, mem_size_t newsize){  mem_size_t size;  mem_size_t ptr, ptr2;  struct mem *mem, *mem2;  /* Expand the size of the allocated memory region so that we can     adjust for alignment. */  newsize = LWIP_MEM_ALIGN_SIZE(newsize);  if(newsize < MIN_SIZE_ALIGNED) {    /* every data block must be at least MIN_SIZE_ALIGNED long */    newsize = MIN_SIZE_ALIGNED;  }  if (newsize > MEM_SIZE_ALIGNED) {    return NULL;  }  LWIP_ASSERT("mem_realloc: legal memory", (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) {    LWIP_DEBUGF(MEM_DEBUG | 3, ("mem_realloc: illegal memory\n"));    return rmem;  }  /* Get the corresponding struct mem ... */  mem = (struct mem *)((u8_t *)rmem - SIZEOF_STRUCT_MEM);  /* ... and its offset pointer */  ptr = (u8_t *)mem - ram;  size = mem->next - ptr - SIZEOF_STRUCT_MEM;  LWIP_ASSERT("mem_realloc can only shrink memory", newsize <= size);  if (newsize > size) {    /* not supported */    return NULL;  }  if (newsize == size) {    /* No change in size, simply return */    return rmem;  }  /* protect the heap from concurrent access */  sys_arch_sem_wait(mem_sem, 0);#if MEM_STATS  lwip_stats.mem.used -= (size - newsize);#endif /* MEM_STATS */  mem2 = (struct mem *)&ram[mem->next];  if(mem2->used == 0) {    /* The next struct is unused, we can simply move it at little */    mem_size_t next;    /* remember the old next pointer */    next = mem2->next;    /* create new struct mem which is moved directly after the shrinked mem */    ptr2 = ptr + SIZEOF_STRUCT_MEM + newsize;    if (lfree == mem2) {      lfree = (struct mem *)&ram[ptr2];    }    mem2 = (struct mem *)&ram[ptr2];    mem2->used = 0;    /* restore the next pointer */    mem2->next = next;    /* link it back to mem */    mem2->prev = ptr;    /* link mem to it */    mem->next = ptr2;    /* last thing to restore linked list: as we have moved mem2,     * let 'mem2->next->prev' point to mem2 again. but only if mem2->next is not     * the end of the heap */    if (mem2->next != MEM_SIZE_ALIGNED) {      ((struct mem *)&ram[mem2->next])->prev = ptr2;    }    /* no need to plug holes, we've already done that */  } else if (newsize + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED <= size) {    /* Next struct is used but there's room for another struct mem with     * at least MIN_SIZE_ALIGNED of data.     * Old size ('size') must be big enough to contain at least 'newsize' plus a struct mem     * ('SIZEOF_STRUCT_MEM') with some data ('MIN_SIZE_ALIGNED').     * @todo we could leave out MIN_SIZE_ALIGNED. We would create an empty     *       region that couldn't hold data, but when mem->next gets freed,     *       the 2 regions would be combined, resulting in more free memory */    ptr2 = ptr + SIZEOF_STRUCT_MEM + newsize;    mem2 = (struct mem *)&ram[ptr2];    if (mem2 < lfree) {      lfree = mem2;    }    mem2->used = 0;    mem2->next = mem->next;    mem2->prev = ptr;    mem->next = ptr2;    if (mem2->next != MEM_SIZE_ALIGNED) {      ((struct mem *)&ram[mem2->next])->prev = ptr2;    }    /* the original mem->next is used, so no need to plug holes! */  }  /* else {    next struct mem is used but size between mem and mem2 is not big enough    to create another struct mem    -> don't do anyhting.     -> the remaining space stays unused since it is too small  } */  sys_sem_signal(mem_sem);  return rmem;}/** * Adam's mem_malloc() plus solution for bug #17922 * Allocate a block of memory with a minimum of 'size' bytes. * * @param size is the minimum size of the requested block in bytes. * @return 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). */void *mem_malloc(mem_size_t size){  mem_size_t ptr, ptr2;  struct mem *mem, *mem2;  if (size == 0) {    return NULL;  }  /* Expand the size of the allocated memory region so that we can     adjust for alignment. */  size = LWIP_MEM_ALIGN_SIZE(size);  if(size < MIN_SIZE_ALIGNED) {    /* every data block must be at least MIN_SIZE_ALIGNED long */    size = MIN_SIZE_ALIGNED;  }  if (size > MEM_SIZE_ALIGNED) {    return NULL;  }  /* protect the heap from concurrent access */  sys_arch_sem_wait(mem_sem, 0);  /* Scan through the heap searching for a free block that is big enough,   * beginning with the lowest free block.   */  for (ptr = (u8_t *)lfree - ram; ptr < MEM_SIZE_ALIGNED - size;       ptr = ((struct mem *)&ram[ptr])->next) {    mem = (struct mem *)&ram[ptr];    if ((!mem->used) &&        (mem->next - (ptr + SIZEOF_STRUCT_MEM)) >= size) {      /* mem is not used and at least perfect fit is possible:       * mem->next - (ptr + SIZEOF_STRUCT_MEM) gives us the 'user data size' of mem */      if (mem->next - (ptr + SIZEOF_STRUCT_MEM) >= (size + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED)) {        /* (in addition to the above, we test if another struct mem (SIZEOF_STRUCT_MEM) containing         * at least MIN_SIZE_ALIGNED of data also fits in the 'user data space' of 'mem')         * -> split large block, create empty remainder,         * remainder must be large enough to contain MIN_SIZE_ALIGNED data: if         * mem->next - (ptr + (2*SIZEOF_STRUCT_MEM)) == size,         * struct mem would fit in but no data between mem2 and mem2->next         * @todo we could leave out MIN_SIZE_ALIGNED. We would create an empty         *       region that couldn't hold data, but when mem->next gets freed,         *       the 2 regions would be combined, resulting in more free memory         */        ptr2 = ptr + SIZEOF_STRUCT_MEM + size;        /* create mem2 struct */        mem2 = (struct mem *)&ram[ptr2];        mem2->used = 0;        mem2->next = mem->next;        mem2->prev = ptr;        /* and insert it between mem and mem->next */        mem->next = ptr2;        mem->used = 1;        if (mem2->next != MEM_SIZE_ALIGNED) {          ((struct mem *)&ram[mem2->next])->prev = ptr2;        }#if MEM_STATS        lwip_stats.mem.used += (size + SIZEOF_STRUCT_MEM);        if (lwip_stats.mem.max < lwip_stats.mem.used) {          lwip_stats.mem.max = lwip_stats.mem.used;        }#endif /* MEM_STATS */      } else {        /* (a mem2 struct does no fit into the user data space of mem and mem->next will always         * be used at this point: if not we have 2 unused structs in a row, plug_holes should have         * take care of this).         * -> near fit or excact fit: do not split, no mem2 creation         * also can't move mem->next directly behind mem, since mem->next         * will always be used at this point!         */        mem->used = 1;#if MEM_STATS        lwip_stats.mem.used += mem->next - ((u8_t *)mem - ram);        if (lwip_stats.mem.max < lwip_stats.mem.used) {          lwip_stats.mem.max = lwip_stats.mem.used;        }#endif /* MEM_STATS */      }      if (mem == lfree) {        /* Find next free block after mem and update lowest free pointer */        while (lfree->used && lfree != ram_end) {          lfree = (struct mem *)&ram[lfree->next];        }        LWIP_ASSERT("mem_malloc: !lfree->used", ((lfree == ram_end) || (!lfree->used)));      }      sys_sem_signal(mem_sem);      LWIP_ASSERT("mem_malloc: allocated memory not above ram_end.",       (mem_ptr_t)mem + SIZEOF_STRUCT_MEM + size <= (mem_ptr_t)ram_end);      LWIP_ASSERT("mem_malloc: allocated memory properly aligned.",       (unsigned long)((u8_t *)mem + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT == 0);      LWIP_ASSERT("mem_malloc: sanity check alignment",        (((mem_ptr_t)mem) & (MEM_ALIGNMENT-1)) == 0);      return (u8_t *)mem + SIZEOF_STRUCT_MEM;    }  }  LWIP_DEBUGF(MEM_DEBUG | 2, ("mem_malloc: could not allocate %"S16_F" bytes\n", (s16_t)size));#if MEM_STATS  ++lwip_stats.mem.err;#endif /* MEM_STATS */  sys_sem_signal(mem_sem);  return NULL;}#endif /* MEM_USE_POOLS *//** * 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. * * @param count number of objects to allocate * @param size size of the objects to allocate * @return pointer to allocated memory / NULL pointer if there is an error */void *mem_calloc(mem_size_t count, mem_size_t size){  void *p;  /* allocate 'count' objects of size 'size' */  p = mem_malloc(count * size);  if (p) {    /* zero the memory */    memset(p, 0, count * size);  }  return p;}#endif /* !MEM_LIBC_MALLOC */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -