Line data Source code
1 : /**
2 : r_memory.c
3 :
4 :
5 : Copyright (C) 2004, Network Resonance, Inc.
6 : Copyright (C) 2006, Network Resonance, Inc.
7 : All Rights Reserved
8 :
9 : Redistribution and use in source and binary forms, with or without
10 : modification, are permitted provided that the following conditions
11 : are met:
12 :
13 : 1. Redistributions of source code must retain the above copyright
14 : notice, this list of conditions and the following disclaimer.
15 : 2. Redistributions in binary form must reproduce the above copyright
16 : notice, this list of conditions and the following disclaimer in the
17 : documentation and/or other materials provided with the distribution.
18 : 3. Neither the name of Network Resonance, Inc. nor the name of any
19 : contributors to this software may be used to endorse or promote
20 : products derived from this software without specific prior written
21 : permission.
22 :
23 : THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
24 : AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 : IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 : ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27 : LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 : CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 : SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 : INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 : CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 : ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 : POSSIBILITY OF SUCH DAMAGE.
34 :
35 :
36 : ekr@rtfm.com Thu Apr 22 20:40:45 2004
37 : */
38 :
39 :
40 : static char *RCSSTRING __UNUSED__="$Id: r_memory.c,v 1.2 2006/08/16 19:39:17 adamcain Exp $";
41 :
42 : #include <string.h>
43 : #include <stddef.h>
44 : #include <assert.h>
45 : #include "r_common.h"
46 : #include "r_memory.h"
47 :
48 : typedef struct r_malloc_chunk_ {
49 : #ifdef SANITY_CHECKS
50 : UINT4 hdr;
51 : #endif
52 : UCHAR type;
53 : UINT4 size;
54 : UCHAR memory[1];
55 : } r_malloc_chunk;
56 :
57 : #define CHUNK_MEMORY_OFFSET offsetof(struct r_malloc_chunk_, memory)
58 : #define GET_CHUNK_ADDR_FROM_MEM_ADDR(memp) \
59 : ((struct r_malloc_chunk *)(((unsigned char*)(memp))-CHUNK_MEMORY_OFFSET))
60 : #define CHUNK_SIZE(size) (size+sizeof(r_malloc_chunk))
61 :
62 : #define HDR_FLAG 0x464c4147
63 :
64 : static UINT4 mem_usage; /* Includes our header */
65 : static UINT4 mem_stats[256]; /* Does not include our header */
66 :
67 0 : void *r_malloc(type,size)
68 : int type;
69 : size_t size;
70 : {
71 : size_t total;
72 : r_malloc_chunk *chunk;
73 :
74 0 : total=size+sizeof(r_malloc_chunk);
75 :
76 0 : if(!(chunk=malloc(total)))
77 0 : return(0);
78 :
79 : #ifdef SANITY_CHECKS
80 0 : chunk->hdr=HDR_FLAG;
81 : #endif
82 0 : chunk->type=type;
83 0 : chunk->size=size;
84 :
85 0 : mem_usage+=CHUNK_SIZE(size);
86 0 : mem_stats[type]+=size;
87 :
88 0 : return(chunk->memory);
89 : }
90 :
91 0 : void *r_calloc(type,number,size)
92 : int type;
93 : size_t number;
94 : size_t size;
95 : {
96 : void *ret;
97 : size_t total;
98 :
99 0 : total=number*size;
100 :
101 0 : if(!(ret=r_malloc(type,total)))
102 0 : return(0);
103 :
104 0 : memset(ret,0,size);
105 :
106 0 : return(ret);
107 : }
108 :
109 0 : void r_free(ptr)
110 : void *ptr;
111 : {
112 : r_malloc_chunk *chunk;
113 :
114 0 : if(!ptr) return;
115 :
116 0 : chunk=(r_malloc_chunk *)GET_CHUNK_ADDR_FROM_MEM_ADDR(ptr);
117 : #ifdef SANITY_CHECKS
118 0 : assert(chunk->hdr==HDR_FLAG);
119 : #endif
120 :
121 0 : mem_usage-=CHUNK_SIZE(chunk->size);
122 0 : mem_stats[chunk->type]-=chunk->size;
123 :
124 0 : free(chunk);
125 : }
126 :
127 0 : void *r_realloc(ptr,size)
128 : void *ptr;
129 : size_t size;
130 : {
131 : r_malloc_chunk *chunk,*nchunk;
132 : size_t total;
133 :
134 0 : if(!ptr) return(r_malloc(255,size));
135 :
136 0 : chunk=(r_malloc_chunk *)GET_CHUNK_ADDR_FROM_MEM_ADDR(ptr);
137 : #ifdef SANITY_CHECKS
138 0 : assert(chunk->hdr==HDR_FLAG);
139 : #endif
140 :
141 0 : total=size + sizeof(r_malloc_chunk);
142 :
143 0 : if(!(nchunk=realloc(chunk,total)))
144 0 : return(0);
145 :
146 0 : mem_usage-=CHUNK_SIZE(nchunk->size);
147 0 : mem_stats[nchunk->type]-=nchunk->size;
148 :
149 0 : nchunk->size=size;
150 0 : mem_usage+=CHUNK_SIZE(nchunk->size);
151 0 : mem_stats[nchunk->type]+=nchunk->size;
152 :
153 0 : return(nchunk->memory);
154 : }
155 :
156 0 : char *r_strdup(str)
157 : const char *str;
158 : {
159 : int len;
160 : char *nstr;
161 :
162 0 : if(!str)
163 0 : return(0);
164 :
165 0 : len=strlen(str)+1;
166 :
167 0 : if(!(nstr=r_malloc(0,len)))
168 0 : return(0);
169 :
170 0 : memcpy(nstr,str,len);
171 :
172 0 : return(nstr);
173 : }
174 :
175 0 : int r_mem_get_usage(usagep)
176 : UINT4 *usagep;
177 : {
178 0 : *usagep=mem_usage;
179 :
180 0 : return(0);
181 : }
182 :
183 0 : int r_memory_dump_stats()
184 : {
185 : int i;
186 :
187 0 : printf("Total memory usage: %d\n",mem_usage);
188 0 : printf("Memory usage by bucket\n");
189 0 : for(i=0;i<256;i++){
190 0 : if(mem_stats[i]){
191 0 : printf("%d\t%d\n",i,mem_stats[i]);
192 : }
193 : }
194 0 : return(0);
195 : }
196 :
197 0 : void *r_malloc_compat(size)
198 : size_t size;
199 : {
200 0 : return(r_malloc(255,size));
201 : }
|