00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifdef HAVE_CONFIG_H
00022 #include "config.h"
00023 #endif
00024
00025 #include <stdlib.h>
00026 #include <string.h>
00027 #include <stdio.h>
00028 #include <assert.h>
00029
00030 #ifdef fid_ENABLE_MEMORY_PROFILING
00031 #undef fid_ENABLE_MEMORY_PROFILING
00032 #endif
00033 #define fid_MEMORY_INTERNAL
00034
00035 #include "libdefs.h"
00036
00037 static size_t memory_peak=0;
00038 static size_t memory_current_size=0;
00039 static fid_Uint64 memory_calls=0;
00040 static fid_Uint64 memory_allocations=0;
00041 static fid_Uint64 memory_deallocations=0;
00042
00043 #define PTR_INC ((size_t)8192)
00044
00045 #define PEAK\
00046 if(memory_current_size > memory_peak)\
00047 {\
00048 memory_peak=memory_current_size;\
00049 }
00050
00051 typedef struct
00052 {
00053 void *ptr;
00054 size_t size;
00055 } Ptrinfo;
00056
00057
00058 static Ptrinfo *memory_pointers=NULL;
00059 static size_t memory_pointers_count=0;
00060
00061
00062 static Ptrinfo *find_pointer(void *ptr)
00063 {
00064 size_t i;
00065
00066 assert(ptr != NULL);
00067
00068 #ifdef S_SPLINT_S
00069 if(memory_pointers == NULL)
00070 {
00071 return NULL;
00072 }
00073 #endif
00074
00075 for(i=0; i < memory_pointers_count; ++i)
00076 {
00077 if(memory_pointers[i].ptr == ptr)
00078 {
00079
00080 return &memory_pointers[i];
00081
00082 }
00083 }
00084 return NULL;
00085 }
00086
00087 static void add_pointer(void *ptr, size_t size)
00088 {
00089 size_t i, j;
00090
00091 assert(ptr != NULL);
00092 assert(size > 0);
00093
00094 if(memory_pointers == NULL)
00095 {
00096 memory_pointers_count=PTR_INC;
00097 if((memory_pointers=
00098 (Ptrinfo *)malloc(memory_pointers_count*sizeof(Ptrinfo))) == NULL)
00099 {
00100 fprintf(stderr,"### %d: out of memory\n",__LINE__);
00101 abort();
00102 }
00103 for(i=0; i < memory_pointers_count; ++i)
00104 {
00105 memory_pointers[i].ptr=NULL;
00106 memory_pointers[i].size=0;
00107 }
00108 }
00109
00110
00111 for(i=0; i < memory_pointers_count; ++i)
00112 {
00113 if(memory_pointers[i].ptr == NULL)
00114 {
00115 break;
00116 }
00117 }
00118
00119
00120 if(i == memory_pointers_count)
00121 {
00122 memory_pointers_count+=PTR_INC;
00123
00124 if((memory_pointers=
00125 (Ptrinfo *)realloc(memory_pointers,
00126 memory_pointers_count*sizeof(Ptrinfo))) == NULL)
00127 {
00128 fprintf(stderr,"### %d: out of memory\n",__LINE__);
00129 abort();
00130 }
00131
00132 for(j=i; j < memory_pointers_count; ++j)
00133 {
00134 memory_pointers[j].ptr=NULL;
00135 memory_pointers[j].size=0;
00136 }
00137 }
00138
00139
00140 memory_pointers[i].ptr=ptr;
00141 memory_pointers[i].size=size;
00142
00143 memory_current_size+=size;
00144 PEAK;
00145 ++memory_allocations;
00146 }
00147
00148 static void remove_pointer(void *ptr)
00149 {
00150 Ptrinfo *ptrinfo;
00151
00152 if(ptr == NULL)
00153 {
00154 return;
00155 }
00156
00157 if((ptrinfo=find_pointer(ptr)) != NULL)
00158 {
00159 memory_current_size-=ptrinfo->size;
00160 ++memory_deallocations;
00161 ptrinfo->ptr=NULL;
00162 ptrinfo->size=0;
00163 }
00164 else
00165 {
00166 fprintf(stderr,"### %d: pointer %p unknown\n",__LINE__,ptr);
00167 abort();
00168 }
00169 }
00170
00171
00172
00173
00174
00175
00176
00177 void *fid_memory_malloc(size_t size)
00178 {
00179 void *block;
00180
00181 ++memory_calls;
00182 if((block=malloc(size)) != NULL)
00183 {
00184 add_pointer(block,size);
00185 }
00186
00187 return block;
00188 }
00189
00190
00191
00192
00193
00194
00195
00196 void *fid_memory_calloc(size_t nmemb, size_t size)
00197 {
00198 void *block;
00199
00200 ++memory_calls;
00201 if((block=calloc(nmemb,size)) != NULL)
00202 {
00203 add_pointer(block,nmemb*size);
00204 }
00205
00206 return block;
00207 }
00208
00209
00210
00211
00212
00213
00214
00215 void *fid_memory_realloc(void *ptr, size_t size)
00216 {
00217 void *block;
00218 Ptrinfo *ptrinfo;
00219
00220 ++memory_calls;
00221 if((block=realloc(ptr,size)) != NULL)
00222 {
00223 if(ptr == NULL)
00224 {
00225
00226 add_pointer(block,size);
00227 }
00228 else if((ptrinfo=find_pointer(ptr)) != NULL)
00229 {
00230
00231 memory_current_size-=ptrinfo->size;
00232 memory_current_size+=size;
00233 PEAK;
00234 ptrinfo->ptr=block;
00235 ptrinfo->size=size;
00236 }
00237 else
00238 {
00239 fprintf(stderr,"### %d: pointer %p unknown\n",__LINE__,ptr);
00240 abort();
00241 }
00242 }
00243 else if(ptr != NULL && size == 0)
00244 {
00245
00246 remove_pointer(ptr);
00247 }
00248
00249 return block;
00250 }
00251
00252
00253
00254
00255
00256
00257
00258 char *fid_memory_strdup(const char *s)
00259 {
00260 char *block;
00261
00262 ++memory_calls;
00263 if((block=strdup(s)) != NULL)
00264 {
00265 add_pointer(block,strlen(s));
00266 }
00267
00268 return block;
00269 }
00270
00271
00272
00273
00274
00275
00276
00277 void fid_memory_free(void *ptr)
00278 {
00279 ++memory_calls;
00280 remove_pointer(ptr);
00281 free(ptr);
00282 }
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300 void fid_memory_query(size_t *peak, size_t *current, fid_Uint64 *allocs,
00301 fid_Uint64 *frees, fid_Uint64 *total)
00302 {
00303 *peak=memory_peak;
00304 *current=memory_current_size;
00305 *allocs=memory_allocations;
00306 *frees=memory_deallocations;
00307 *total=memory_calls;
00308 }
00309
00310 #define MB(S) (((double)(S))/1024.0/1024.0)
00311
00312
00313
00314
00315
00316
00317 void fid_memory_show_usage(FILE *stream)
00318 {
00319 fprintf(stream,
00320 "\n"
00321 "###########################\n"
00322 "### MEMORY STATISTICS ###\n"
00323 "###########################\n"
00324 "Memory peak : %lu bytes (%.2f MB)\n"
00325 "Current memory consumption: %lu bytes (%.2f MB)\n"
00326 "Number of allocations : " fid_U64FMT "\n"
00327 "Number of deallocations : " fid_U64FMT "\n"
00328 "Total number of calls : " fid_U64FMT "\n"
00329 "###########################\n",
00330 (unsigned long)memory_peak,MB(memory_peak),
00331 (unsigned long)memory_current_size,MB(memory_current_size),
00332 memory_allocations,memory_deallocations,memory_calls);
00333 }