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

📄 mem.c

📁 lwip在ucos上的移植源码
💻 C
字号:
/* * Copyright (c) 2001, Swedish Institute of Computer Science. * All rights reserved.  * * Redistribution and use in source and binary forms, with or without  * modification, are permitted provided that the following conditions  * are met:  * 1. Redistributions of source code must retain the above copyright  *    notice, this list of conditions and the following disclaimer.  * 2. Redistributions in binary form must reproduce the above copyright  *    notice, this list of conditions and the following disclaimer in the  *    documentation and/or other materials provided with the distribution.  * 3. Neither the name of the Institute nor the names of its contributors  *    may be used to endorse or promote products derived from this software  *    without specific prior written permission.  * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF  * SUCH DAMAGE.  * * This file is part of the lwIP TCP/IP stack. *  * Author: Adam Dunkels <adam@sics.se> * * $Id: mem.c,v 1.1 2003/05/21 10:35:27 chenyu Exp $ *//*-----------------------------------------------------------------------------------*//* mem.c * * Memory manager. * *//*-----------------------------------------------------------------------------------*/#include "lwip/debug.h"#include "lwip/arch.h"#include "lwip/opt.h"#include "lwip/def.h"#include "lwip/mem.h"#include "lwip/sys.h"#include "lwip/stats.h"#if MEM_RECLAIMstruct mem_reclaim_ {  struct mem_reclaim_ *next;  mem_reclaim_func f;  void *arg;  };#endif /* MEM_RECLAIM */struct mem {  mem_size_t next, prev;  u8_t used;#if MEM_ALIGNMENT == 2  u8_t dummy;#endif /* MEM_ALIGNEMNT == 2 */};static struct mem *ram_end;static u8_t ram[MEM_ALIGN_SIZE(MEM_SIZE + sizeof(struct mem))];#define MIN_SIZE 12#define SIZEOF_STRUCT_MEM MEM_ALIGN_SIZE(sizeof(struct mem))/*#define SIZEOF_STRUCT_MEM (sizeof(struct mem) + \                          (((sizeof(struct mem) % MEM_ALIGNMENT) == 0)? 0 : \                          (4 - (sizeof(struct mem) % MEM_ALIGNMENT))))*/static struct mem *lfree;   /* pointer to the lowest free block */#if MEM_RECLAIMstatic struct mem_reclaim_ *mrlist;#endif /* MEM_RECLAIM */static sys_sem_t mem_sem;/*-----------------------------------------------------------------------------------*/static voidplug_holes(struct mem *mem){  struct mem *nmem;  struct mem *pmem;  ASSERT("plug_holes: mem >= ram", (u8_t *)mem >= ram);  ASSERT("plug_holes: mem < ram_end", (u8_t *)mem < (u8_t *)ram_end);  ASSERT("plug_holes: mem->used == 0", mem->used == 0);    /* plug hole forward */  ASSERT("plug_holes: mem->next <= MEM_SIZE", mem->next <= MEM_SIZE);    nmem = (struct mem *)&ram[mem->next];  if(mem != nmem && nmem->used == 0 && (u8_t *)nmem != (u8_t *)ram_end) {    if(lfree == nmem) {      lfree = mem;    }    mem->next = nmem->next;    ((struct mem *)&ram[nmem->next])->prev = (u8_t *)mem - ram;  }  /* plug hole backward */  pmem = (struct mem *)&ram[mem->prev];  if(pmem != mem && pmem->used == 0) {    if(lfree == mem) {      lfree = pmem;    }    pmem->next = mem->next;    ((struct mem *)&ram[mem->next])->prev = (u8_t *)pmem - ram;  }}/*-----------------------------------------------------------------------------------*/voidmem_init(void){  struct mem *mem;  bzero(ram, MEM_SIZE);  mem = (struct mem *)ram;  mem->next = MEM_SIZE;  mem->prev = 0;  mem->used = 0;  ram_end = (struct mem *)&ram[MEM_SIZE];  ram_end->used = 1;  ram_end->next = MEM_SIZE;  ram_end->prev = MEM_SIZE;  mem_sem = sys_sem_new(1);  lfree = (struct mem *)ram;#if MEM_RECLAIM  mrlist = NULL;#endif /* MEM_RECLAIM */  #ifdef MEM_STATS  stats.mem.avail = MEM_SIZE;#endif /* MEM_STATS */}/*-----------------------------------------------------------------------------------*/#if MEM_RECLAIMvoidmem_reclaim(unsigned int size){  struct mem_reclaim_ *mr;  int rec;  rec = 0;        for(mr = mrlist; mr != NULL; mr = mr->next) {    DEBUGF(MEM_DEBUG, ("mem_malloc: calling reclaimer\n"));    rec += mr->f(mr->arg, size);  }#ifdef MEM_STATS  stats.mem.reclaimed += rec;#endif /* MEM_STATS */}#endif /* MEM_RECLAIM *//*-----------------------------------------------------------------------------------*/void *mem_malloc2(mem_size_t size){  void *mem;  mem = mem_malloc(size);#if MEM_RECLAIM        if(mem == NULL) {    mem_reclaim(size);        mem = mem_malloc(size);  }#endif /* MEM_RECLAIM */  return mem;}/*-----------------------------------------------------------------------------------*/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. */  if((size % MEM_ALIGNMENT) != 0) {    size += MEM_ALIGNMENT - ((size + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT);  }    if(size > MEM_SIZE) {    return NULL;  }    sys_sem_wait(mem_sem);  for(ptr = (u8_t *)lfree - ram; ptr < MEM_SIZE; ptr = ((struct mem *)&ram[ptr])->next) {    mem = (struct mem *)&ram[ptr];    if(!mem->used &&       mem->next - (ptr + SIZEOF_STRUCT_MEM) >= size + SIZEOF_STRUCT_MEM) {      ptr2 = ptr + SIZEOF_STRUCT_MEM + size;      mem2 = (struct mem *)&ram[ptr2];      mem2->prev = ptr;            mem2->next = mem->next;      mem->next = ptr2;            if(mem2->next != MEM_SIZE) {        ((struct mem *)&ram[mem2->next])->prev = ptr2;      }            mem2->used = 0;            mem->used = 1;#ifdef MEM_STATS      stats.mem.used += size;      /*      if(stats.mem.max < stats.mem.used) {        stats.mem.max = stats.mem.used;	} */      if(stats.mem.max < ptr2) {        stats.mem.max = ptr2;      }      #ifdef MEM_PERF      mem_perf_output();#endif /* MEM_PERF */  #endif /* MEM_STATS */      if(mem == lfree) {	/* Find next free block after mem */        while(lfree->used && lfree != ram_end) {	  lfree = (struct mem *)&ram[lfree->next];        }        ASSERT("mem_malloc: !lfree->used", !lfree->used);      }      sys_sem_signal(mem_sem);      ASSERT("mem_malloc: allocated memory not above ram_end.",	     (u32_t)mem + SIZEOF_STRUCT_MEM + size <= (u32_t)ram_end);      ASSERT("mem_malloc: allocated memory properly aligned.",	     (unsigned long)((u8_t *)mem + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT == 0);      return (u8_t *)mem + SIZEOF_STRUCT_MEM;    }      }  DEBUGF(MEM_DEBUG, ("mem_malloc: could not allocate %d bytes\n", (int)size));#ifdef MEM_STATS  ++stats.mem.err;#endif /* MEM_STATS */    sys_sem_signal(mem_sem);  return NULL;}/*-----------------------------------------------------------------------------------*/voidmem_free(void *rmem){  struct mem *mem;  if(rmem == NULL) {    return;  }    sys_sem_wait(mem_sem);  ASSERT("mem_free: 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) {    DEBUGF(MEM_DEBUG, ("mem_free: illegal memory\n"));#ifdef MEM_STATS    ++stats.mem.err;#endif /* MEM_STATS */    return;  }  mem = (struct mem *)((u8_t *)rmem - SIZEOF_STRUCT_MEM);  ASSERT("mem_free: mem->used", mem->used);    mem->used = 0;  if(mem < lfree) {    lfree = mem;  }  #ifdef MEM_STATS  stats.mem.used -= mem->next - ((u8_t *)mem - ram) - SIZEOF_STRUCT_MEM;#ifdef MEM_PERF  mem_perf_output();#endif /* MEM_PERF */  #endif /* MEM_STATS */  plug_holes(mem);  sys_sem_signal(mem_sem);}/*-----------------------------------------------------------------------------------*/void *mem_reallocm(void *rmem, mem_size_t newsize){  void *nmem;  nmem = mem_malloc(newsize);  if(nmem == NULL) {    return mem_realloc(rmem, newsize);  }  bcopy(rmem, nmem, newsize);  mem_free(rmem);  return nmem;}/*-----------------------------------------------------------------------------------*/void *mem_realloc(void *rmem, mem_size_t newsize){  mem_size_t size;  mem_size_t ptr, ptr2;  struct mem *mem, *mem2;    sys_sem_wait(mem_sem);    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) {    DEBUGF(MEM_DEBUG, ("mem_free: illegal memory\n"));    return rmem;  }  mem = (struct mem *)((u8_t *)rmem - SIZEOF_STRUCT_MEM);  ptr = (u8_t *)mem - ram;  size = mem->next - ptr - SIZEOF_STRUCT_MEM;#ifdef MEM_STATS  stats.mem.used -= (size - newsize);#ifdef MEM_PERF  mem_perf_output();#endif /* MEM_PERF */ #endif /* MEM_STATS */    if(newsize + SIZEOF_STRUCT_MEM + MIN_SIZE < size) {    ptr2 = ptr + SIZEOF_STRUCT_MEM + newsize;    mem2 = (struct mem *)&ram[ptr2];    mem2->used = 0;    mem2->next = mem->next;    mem2->prev = ptr;    mem->next = ptr2;    if(mem2->next != MEM_SIZE) {      ((struct mem *)&ram[mem2->next])->prev = ptr2;    }    plug_holes(mem2);  }  sys_sem_signal(mem_sem);    return rmem;}/*-----------------------------------------------------------------------------------*/#if MEM_RECLAIMvoidmem_register_reclaim(mem_reclaim_func f, void *arg){  struct mem_reclaim_ *mr;  mr = mem_malloc(sizeof(struct mem_reclaim_));  if(mr == NULL) {    return;  }  mr->next = mrlist;  mrlist = mr;  mr->f = f;  mr->arg = arg;}     #endif /* MEM_RECLAIM *//*-----------------------------------------------------------------------------------*/

⌨️ 快捷键说明

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