Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

mem.c File Reference

#include "lwip/arch.h"
#include "lwip/opt.h"
#include "lwip/def.h"
#include "lwip/mem.h"
#include "lwip/sys.h"
#include "lwip/stats.h"

Include dependency graph for mem.c:

Go to the source code of this file.

Data Structures

struct  mem

Defines

#define MIN_SIZE   12
#define SIZEOF_STRUCT_MEM   MEM_ALIGN_SIZE(sizeof(struct mem))

Functions

void plug_holes (struct mem *mem)
void mem_init (void)
void mem_free (void *rmem)
void * mem_reallocm (void *rmem, mem_size_t newsize)
void * mem_realloc (void *rmem, mem_size_t newsize)
void * mem_malloc (mem_size_t size)

Variables

memram_end
u8_t ram [MEM_SIZE+sizeof(struct mem)+MEM_ALIGNMENT]
memlfree
sys_sem_t mem_sem


Define Documentation

#define MIN_SIZE   12
 

Definition at line 72 of file mem.c.

#define SIZEOF_STRUCT_MEM   MEM_ALIGN_SIZE(sizeof(struct mem))
 

Definition at line 73 of file mem.c.

Referenced by mem_free(), mem_malloc(), and mem_realloc().


Function Documentation

void mem_free void *  rmem  ) 
 

Definition at line 143 of file mem.c.

References DEBUGF, lfree, LWIP_ASSERT, MEM_DEBUG, mem_sem, mem::next, NULL, plug_holes(), ram, ram_end, SIZEOF_STRUCT_MEM, sys_sem_signal(), sys_sem_wait(), and u8_t.

Referenced by close_conn(), conn_err(), dhcp_free_reply(), dhcp_inform(), dhcp_start(), dhcp_stop(), dhcp_unfold_reply(), mem_reallocm(), netif_add(), netif_remove(), and pbuf_free().

00144 {
00145   struct mem *mem;
00146 
00147   if(rmem == NULL) {
00148     return;
00149   }
00150   
00151   sys_sem_wait(mem_sem);
00152 
00153   LWIP_ASSERT("mem_free: legal memory", (u8_t *)rmem >= (u8_t *)ram &&
00154          (u8_t *)rmem < (u8_t *)ram_end);
00155   
00156   
00157   if((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) {
00158     DEBUGF(MEM_DEBUG | 3, ("mem_free: illegal memory\n"));
00159 #ifdef MEM_STATS
00160     ++lwip_stats.mem.err;
00161 #endif /* MEM_STATS */
00162     return;
00163   }
00164   mem = (struct mem *)((u8_t *)rmem - SIZEOF_STRUCT_MEM);
00165 
00166   LWIP_ASSERT("mem_free: mem->used", mem->used);
00167   
00168   mem->used = 0;
00169 
00170   if(mem < lfree) {
00171     lfree = mem;
00172   }
00173   
00174 #ifdef MEM_STATS
00175   lwip_stats.mem.used -= mem->next - ((u8_t *)mem - ram) - SIZEOF_STRUCT_MEM;
00176   
00177 #endif /* MEM_STATS */
00178   plug_holes(mem);
00179   sys_sem_signal(mem_sem);
00180 }

Here is the call graph for this function:

void mem_init void   ) 
 

Definition at line 119 of file mem.c.

References lfree, mem_sem, mem::next, mem::prev, ram, ram_end, and sys_sem_new().

00120 {
00121   struct mem *mem;
00122 
00123   memset(ram, 0, MEM_SIZE);
00124   mem = (struct mem *)ram;
00125   mem->next = MEM_SIZE;
00126   mem->prev = 0;
00127   mem->used = 0;
00128   ram_end = (struct mem *)&ram[MEM_SIZE];
00129   ram_end->used = 1;
00130   ram_end->next = MEM_SIZE;
00131   ram_end->prev = MEM_SIZE;
00132 
00133   mem_sem = sys_sem_new(1);
00134 
00135   lfree = (struct mem *)ram;
00136 
00137 #ifdef MEM_STATS
00138   lwip_stats.mem.avail = MEM_SIZE;
00139 #endif /* MEM_STATS */
00140 }

Here is the call graph for this function:

void* mem_malloc mem_size_t  size  ) 
 

Definition at line 248 of file mem.c.

References DEBUGF, lfree, LWIP_ASSERT, MEM_DEBUG, mem_sem, mem_size_t, mem::next, NULL, mem::prev, ram, ram_end, SIZEOF_STRUCT_MEM, sys_sem_signal(), sys_sem_wait(), u32_t, and u8_t.

Referenced by dhcp_inform(), dhcp_start(), dhcp_unfold_reply(), http_accept(), mem_reallocm(), netif_add(), pbuf_alloc(), rt_3c905cif_init(), and rt_rtl8139if_init().

00249 {
00250   mem_size_t ptr, ptr2;
00251   struct mem *mem, *mem2;
00252 
00253   if(size == 0) {
00254     return NULL;
00255   }
00256 
00257   /* Expand the size of the allocated memory region so that we can
00258      adjust for alignment. */
00259   if((size % MEM_ALIGNMENT) != 0) {
00260     size += MEM_ALIGNMENT - ((size + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT);
00261   }
00262   
00263   if(size > MEM_SIZE) {
00264     return NULL;
00265   }
00266   
00267   sys_sem_wait(mem_sem);
00268 
00269   for(ptr = (u8_t *)lfree - ram; ptr < MEM_SIZE; ptr = ((struct mem *)&ram[ptr])->next) {
00270     mem = (struct mem *)&ram[ptr];
00271     if(!mem->used &&
00272        mem->next - (ptr + SIZEOF_STRUCT_MEM) >= size + SIZEOF_STRUCT_MEM) {
00273       ptr2 = ptr + SIZEOF_STRUCT_MEM + size;
00274       mem2 = (struct mem *)&ram[ptr2];
00275 
00276       mem2->prev = ptr;      
00277       mem2->next = mem->next;
00278       mem->next = ptr2;      
00279       if(mem2->next != MEM_SIZE) {
00280         ((struct mem *)&ram[mem2->next])->prev = ptr2;
00281       }
00282       
00283       mem2->used = 0;      
00284       mem->used = 1;
00285 #ifdef MEM_STATS
00286       lwip_stats.mem.used += size;
00287       /*      if(lwip_stats.mem.max < lwip_stats.mem.used) {
00288         lwip_stats.mem.max = lwip_stats.mem.used;
00289         } */
00290       if(lwip_stats.mem.max < ptr2) {
00291         lwip_stats.mem.max = ptr2;
00292       }      
00293 #endif /* MEM_STATS */
00294 
00295       if(mem == lfree) {
00296         /* Find next free block after mem */
00297         while(lfree->used && lfree != ram_end) {
00298           lfree = (struct mem *)&ram[lfree->next];
00299         }
00300         LWIP_ASSERT("mem_malloc: !lfree->used", !lfree->used);
00301       }
00302       sys_sem_signal(mem_sem);
00303       LWIP_ASSERT("mem_malloc: allocated memory not above ram_end.",
00304              (u32_t)mem + SIZEOF_STRUCT_MEM + size <= (u32_t)ram_end);
00305       LWIP_ASSERT("mem_malloc: allocated memory properly aligned.",
00306              (unsigned long)((u8_t *)mem + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT == 0);
00307       return (u8_t *)mem + SIZEOF_STRUCT_MEM;
00308     }    
00309   }
00310   DEBUGF(MEM_DEBUG | 2, ("mem_malloc: could not allocate %d bytes\n", (int)size));
00311 #ifdef MEM_STATS
00312   ++lwip_stats.mem.err;
00313 #endif /* MEM_STATS */  
00314   sys_sem_signal(mem_sem);
00315   return NULL;
00316 }

Here is the call graph for this function:

void* mem_realloc void *  rmem,
mem_size_t  newsize
 

Definition at line 196 of file mem.c.

References DEBUGF, LWIP_ASSERT, MEM_DEBUG, mem_sem, mem_size_t, MIN_SIZE, mem::next, NULL, plug_holes(), mem::prev, ram, ram_end, SIZEOF_STRUCT_MEM, sys_sem_signal(), sys_sem_wait(), and u8_t.

Referenced by mem_reallocm(), and pbuf_realloc().

00197 {
00198   mem_size_t size;
00199   mem_size_t ptr, ptr2;
00200   struct mem *mem, *mem2;
00201 
00202   /* Expand the size of the allocated memory region so that we can
00203      adjust for alignment. */
00204   if((newsize % MEM_ALIGNMENT) != 0) {
00205    newsize += MEM_ALIGNMENT - ((newsize + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT);
00206   }
00207   
00208   if(newsize > MEM_SIZE) {
00209     return NULL;
00210   }
00211   
00212   sys_sem_wait(mem_sem);
00213   
00214   LWIP_ASSERT("mem_realloc: legal memory", (u8_t *)rmem >= (u8_t *)ram &&
00215          (u8_t *)rmem < (u8_t *)ram_end);
00216   
00217   if((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) {
00218     DEBUGF(MEM_DEBUG | 3, ("mem_realloc: illegal memory\n"));
00219     return rmem;
00220   }
00221   mem = (struct mem *)((u8_t *)rmem - SIZEOF_STRUCT_MEM);
00222 
00223   ptr = (u8_t *)mem - ram;
00224 
00225   size = mem->next - ptr - SIZEOF_STRUCT_MEM;
00226 #ifdef MEM_STATS
00227   lwip_stats.mem.used -= (size - newsize);
00228 #endif /* MEM_STATS */
00229   
00230   if(newsize + SIZEOF_STRUCT_MEM + MIN_SIZE < size) {
00231     ptr2 = ptr + SIZEOF_STRUCT_MEM + newsize;
00232     mem2 = (struct mem *)&ram[ptr2];
00233     mem2->used = 0;
00234     mem2->next = mem->next;
00235     mem2->prev = ptr;
00236     mem->next = ptr2;
00237     if(mem2->next != MEM_SIZE) {
00238       ((struct mem *)&ram[mem2->next])->prev = ptr2;
00239     }
00240 
00241     plug_holes(mem2);
00242   }
00243   sys_sem_signal(mem_sem);  
00244   return rmem;
00245 }

Here is the call graph for this function:

void* mem_reallocm void *  rmem,
mem_size_t  newsize
 

Definition at line 183 of file mem.c.

References mem_free(), mem_malloc(), mem_realloc(), mem_size_t, and NULL.

00184 {
00185   void *nmem;
00186   nmem = mem_malloc(newsize);
00187   if(nmem == NULL) {
00188     return mem_realloc(rmem, newsize);
00189   }
00190   memcpy(nmem, rmem, newsize);
00191   mem_free(rmem);
00192   return nmem;
00193 }

Here is the call graph for this function:

void plug_holes struct mem mem  )  [static]
 

Definition at line 85 of file mem.c.

References lfree, LWIP_ASSERT, mem::next, mem::prev, ram, ram_end, and u8_t.

Referenced by mem_free(), and mem_realloc().

00086 {
00087   struct mem *nmem;
00088   struct mem *pmem;
00089 
00090   LWIP_ASSERT("plug_holes: mem >= ram", (u8_t *)mem >= ram);
00091   LWIP_ASSERT("plug_holes: mem < ram_end", (u8_t *)mem < (u8_t *)ram_end);
00092   LWIP_ASSERT("plug_holes: mem->used == 0", mem->used == 0);
00093   
00094   /* plug hole forward */
00095   LWIP_ASSERT("plug_holes: mem->next <= MEM_SIZE", mem->next <= MEM_SIZE);
00096   
00097   nmem = (struct mem *)&ram[mem->next];
00098   if(mem != nmem && nmem->used == 0 && (u8_t *)nmem != (u8_t *)ram_end) {
00099     if(lfree == nmem) {
00100       lfree = mem;
00101     }
00102     mem->next = nmem->next;
00103     ((struct mem *)&ram[nmem->next])->prev = (u8_t *)mem - ram;
00104   }
00105 
00106   /* plug hole backward */
00107   pmem = (struct mem *)&ram[mem->prev];
00108   if(pmem != mem && pmem->used == 0) {
00109     if(lfree == mem) {
00110       lfree = pmem;
00111     }
00112     pmem->next = mem->next;
00113     ((struct mem *)&ram[mem->next])->prev = (u8_t *)pmem - ram;
00114   }
00115 
00116 }


Variable Documentation

struct mem* lfree [static]
 

Definition at line 79 of file mem.c.

Referenced by mem_free(), mem_init(), mem_malloc(), and plug_holes().

sys_sem_t mem_sem [static]
 

Definition at line 81 of file mem.c.

Referenced by mem_free(), mem_init(), mem_malloc(), and mem_realloc().

u8_t ram[MEM_SIZE + sizeof(struct mem) + MEM_ALIGNMENT] [static]
 

Definition at line 70 of file mem.c.

Referenced by mem_free(), mem_init(), mem_malloc(), mem_realloc(), and plug_holes().

struct mem* ram_end [static]
 

Definition at line 69 of file mem.c.

Referenced by mem_free(), mem_init(), mem_malloc(), mem_realloc(), and plug_holes().


Generated on Wed Jan 14 12:59:06 2004 for RTL-lwIP-0.4 by doxygen 1.3.4