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 #include <string.h>
40 #include <stddef.h>
41 #include <assert.h>
42 #include "r_common.h"
43 #include "r_memory.h"
44
45 typedef struct r_malloc_chunk_ {
46 #ifdef SANITY_CHECKS
47 UINT4 hdr;
48 #endif
49 UCHAR type;
50 UINT4 size;
51 UCHAR memory[1];
52 } r_malloc_chunk;
53
54 #define CHUNK_MEMORY_OFFSET offsetof(struct r_malloc_chunk_, memory)
55 #define GET_CHUNK_ADDR_FROM_MEM_ADDR(memp) \
56 ((struct r_malloc_chunk *)(((unsigned char*)(memp))-CHUNK_MEMORY_OFFSET))
57 #define CHUNK_SIZE(size) (size+sizeof(r_malloc_chunk))
58
59 #define HDR_FLAG 0x464c4147
60
61 static UINT4 mem_usage; /* Includes our header */
62 static UINT4 mem_stats[256]; /* Does not include our header */
63
r_malloc(type,size)64 void *r_malloc(type,size)
65 int type;
66 size_t size;
67 {
68 size_t total;
69 r_malloc_chunk *chunk;
70
71 total=size+sizeof(r_malloc_chunk);
72
73 if(!(chunk=malloc(total)))
74 return(0);
75
76 #ifdef SANITY_CHECKS
77 chunk->hdr=HDR_FLAG;
78 #endif
79 chunk->type=type;
80 chunk->size=size;
81
82 mem_usage+=CHUNK_SIZE(size);
83 mem_stats[type]+=size;
84
85 return(chunk->memory);
86 }
87
r_calloc(type,number,size)88 void *r_calloc(type,number,size)
89 int type;
90 size_t number;
91 size_t size;
92 {
93 void *ret;
94 size_t total;
95
96 total=number*size;
97
98 if(!(ret=r_malloc(type,total)))
99 return(0);
100
101 memset(ret,0,size);
102
103 return(ret);
104 }
105
r_free(ptr)106 void r_free(ptr)
107 void *ptr;
108 {
109 r_malloc_chunk *chunk;
110
111 if(!ptr) return;
112
113 chunk=(r_malloc_chunk *)GET_CHUNK_ADDR_FROM_MEM_ADDR(ptr);
114 #ifdef SANITY_CHECKS
115 assert(chunk->hdr==HDR_FLAG);
116 #endif
117
118 mem_usage-=CHUNK_SIZE(chunk->size);
119 mem_stats[chunk->type]-=chunk->size;
120
121 free(chunk);
122 }
123
r_realloc(ptr,size)124 void *r_realloc(ptr,size)
125 void *ptr;
126 size_t size;
127 {
128 r_malloc_chunk *chunk,*nchunk;
129 size_t total;
130
131 if(!ptr) return(r_malloc(255,size));
132
133 chunk=(r_malloc_chunk *)GET_CHUNK_ADDR_FROM_MEM_ADDR(ptr);
134 #ifdef SANITY_CHECKS
135 assert(chunk->hdr==HDR_FLAG);
136 #endif
137
138 total=size + sizeof(r_malloc_chunk);
139
140 if(!(nchunk=realloc(chunk,total)))
141 return(0);
142
143 mem_usage-=CHUNK_SIZE(nchunk->size);
144 mem_stats[nchunk->type]-=nchunk->size;
145
146 nchunk->size=size;
147 mem_usage+=CHUNK_SIZE(nchunk->size);
148 mem_stats[nchunk->type]+=nchunk->size;
149
150 return(nchunk->memory);
151 }
152
r_strdup(str)153 char *r_strdup(str)
154 const char *str;
155 {
156 int len;
157 char *nstr;
158
159 if(!str)
160 return(0);
161
162 len=strlen(str)+1;
163
164 if(!(nstr=r_malloc(0,len)))
165 return(0);
166
167 memcpy(nstr,str,len);
168
169 return(nstr);
170 }
171
r_mem_get_usage(usagep)172 int r_mem_get_usage(usagep)
173 UINT4 *usagep;
174 {
175 *usagep=mem_usage;
176
177 return(0);
178 }
179
r_memory_dump_stats()180 int r_memory_dump_stats()
181 {
182 int i;
183
184 printf("Total memory usage: %d\n",mem_usage);
185 printf("Memory usage by bucket\n");
186 for(i=0;i<256;i++){
187 if(mem_stats[i]){
188 printf("%d\t%d\n",i,mem_stats[i]);
189 }
190 }
191 return(0);
192 }
193
r_malloc_compat(size)194 void *r_malloc_compat(size)
195 size_t size;
196 {
197 return(r_malloc(255,size));
198 }
199