• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

contrib/maloc/src/vsys/vmem.c

00001 /*
00002  * ***************************************************************************
00003  * MALOC = < Minimal Abstraction Layer for Object-oriented C >
00004  * Copyright (C) 1994--2008 Michael Holst
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00019  *
00020  * rcsid="$Id: vmem.c,v 1.15 2008/03/12 05:13:59 fetk Exp $"
00021  * ***************************************************************************
00022  */
00023 
00024 /*
00025  * ***************************************************************************
00026  * File:     vmem.c
00027  *
00028  * Purpose:  Class Vmem: methods.
00029  *
00030  * Author:   Michael Holst
00031  * ***************************************************************************
00032  */
00033 
00034 #include "vmem_p.h"
00035 
00036 VEMBED(rcsid="$Id: vmem.c,v 1.15 2008/03/12 05:13:59 fetk Exp $")
00037 
00038 /* total and misc (default) malloc/free tracking */
00039 VPRIVATE Vmem vmemTotal, vmemMisc;
00040 VPRIVATE size_t vmemInit=0;
00041 
00042 /*
00043  * ***************************************************************************
00044  * Class Vmem: Inlineable methods
00045  * ***************************************************************************
00046  */
00047 #if !defined(VINLINE_MALOC)
00048 
00049 #endif /* if !defined(VINLINE_MALOC) */
00050 /*
00051  * ***************************************************************************
00052  * Class Vmem: Non-inlineable methods
00053  * ***************************************************************************
00054  */
00055 
00056 /*
00057  * ***************************************************************************
00058  * Routine:  Vmem_init
00059  *
00060  * Purpose:  Initialize the total log and the catch-all misc log.
00061  *
00062  * Author:   Michael Holst
00063  * ***************************************************************************
00064  */
00065 VPRIVATE void Vmem_init(void)
00066 {
00067     if (!vmemInit) {
00068 
00069         strncpy(vmemTotal.name, "TOTAL", VMAX_ARGLEN);
00070         vmemTotal.mallocBytes = 0;
00071         vmemTotal.freeBytes = 0;
00072         vmemTotal.highWater = 0;
00073         vmemTotal.mallocAreas = 0;
00074 
00075         strncpy(vmemMisc.name, "MISC", VMAX_ARGLEN);
00076         vmemMisc.mallocBytes = 0;
00077         vmemMisc.freeBytes = 0;
00078         vmemMisc.highWater = 0;
00079         vmemMisc.mallocAreas = 0;
00080 
00081         vmemInit = 1;
00082     }
00083 }
00084 
00085 /*
00086  * ***************************************************************************
00087  * Routine:  Vmem_bytesTotal
00088  *
00089  * Purpose:  Return total size of ALL currently ACTIVE malloc areas that
00090  *           went through Vmem_malloc.  This is the current memory footprint.
00091  *
00092  * Author:   Michael Holst
00093  * ***************************************************************************
00094  */
00095 VPUBLIC size_t Vmem_bytesTotal(void)
00096 {
00097     Vmem_init();
00098     return (vmemTotal.mallocBytes - vmemTotal.freeBytes);
00099 }
00100 
00101 /*
00102  * ***************************************************************************
00103  * Routine:  Vmem_mallocBytesTotal
00104  *
00105  * Purpose:  Return total size of ALL malloc areas that went through
00106  *           Vmem_malloc (even if they have been subsequently freed).
00107  *
00108  * Author:   Michael Holst
00109  * ***************************************************************************
00110  */
00111 VPUBLIC size_t Vmem_mallocBytesTotal(void)
00112 {
00113     Vmem_init();
00114     return vmemTotal.mallocBytes;
00115 }
00116 
00117 /*
00118  * ***************************************************************************
00119  * Routine:  Vmem_freeBytesTotal
00120  *
00121  * Purpose:  Return total size of ALL freed malloc areas that
00122  *           went through Vmem_free.
00123  *
00124  * Author:   Michael Holst
00125  * ***************************************************************************
00126  */
00127 VPUBLIC size_t Vmem_freeBytesTotal(void)
00128 {
00129     Vmem_init();
00130     return vmemTotal.freeBytes;
00131 }
00132 
00133 /*
00134  * ***************************************************************************
00135  * Routine:  Vmem_highWaterTotal
00136  *
00137  * Purpose:  Return the high-water malloc bytemark hit by ALL active
00138  *           malloc areas; this is the largest active malloc total hit at
00139  *           one time by areas obtained through Vmem_malloc.
00140  *
00141  * Author:   Michael Holst
00142  * ***************************************************************************
00143  */
00144 VPUBLIC size_t Vmem_highWaterTotal(void)
00145 {
00146     Vmem_init();
00147     return vmemTotal.highWater;
00148 }
00149 
00150 /*
00151  * ***************************************************************************
00152  * Routine:  Vmem_mallocAreasTotal
00153  *
00154  * Purpose:  Return the total number of ALL individual active malloc areas.
00155  *
00156  * Author:   Michael Holst
00157  * ***************************************************************************
00158  */
00159 VPUBLIC size_t Vmem_mallocAreasTotal(void)
00160 {
00161     Vmem_init();
00162     return vmemTotal.mallocAreas;
00163 }
00164 
00165 /*
00166  * ***************************************************************************
00167  * Routine:  Vmem_printTotal
00168  *
00169  * Purpose:  Print current memory statistics for all malloc areas that have
00170  *           gone through Vmem_malloc and Vmem_free.
00171  *
00172  * Author:   Michael Holst
00173  * ***************************************************************************
00174  */
00175 VPUBLIC void Vmem_printTotal(void)
00176 {
00177     Vmem_init();
00178     fprintf(stderr,"%12ld %12ld %12ld %12ld %12ld %% %s\n",
00179         (vmemTotal.mallocBytes-vmemTotal.freeBytes),
00180         vmemTotal.mallocAreas, vmemTotal.mallocBytes,
00181         vmemTotal.freeBytes, vmemTotal.highWater,
00182         vmemTotal.name);
00183 }
00184 
00185 /*
00186  * ***************************************************************************
00187  * Routine:  Vmem_ctor
00188  *
00189  * Purpose:  Construct the dynamic memory allocation logging object.
00190  *
00191  * Author:   Michael Holst
00192  * ***************************************************************************
00193  */
00194 VPUBLIC Vmem *Vmem_ctor(char *name)
00195 {
00196     Vmem *thee;
00197 
00198     thee = Vmem_malloc( VNULL, 1, sizeof(Vmem) );
00199     VASSERT( thee != VNULL );
00200 
00201     strncpy( thee->name, name, VMAX_ARGLEN );
00202     thee->mallocBytes = 0;
00203     thee->freeBytes = 0;
00204     thee->highWater = 0;
00205     thee->mallocAreas = 0;
00206 
00207     return thee;
00208 }
00209 
00210 /*
00211  * ***************************************************************************
00212  * Routine:  Vmem_dtor
00213  *
00214  * Purpose:  Destruct the dynamic memory allocation logging object.
00215  *
00216  * Author:   Michael Holst
00217  * ***************************************************************************
00218  */
00219 VPUBLIC void Vmem_dtor(Vmem **thee)
00220 {
00221     Vmem_free( VNULL, 1, sizeof(Vmem), (void**)thee );
00222 }
00223 
00224 /*
00225  * ***************************************************************************
00226  * Routine:  Vmem_malloc
00227  *
00228  * Purpose:  A logged version of malloc.
00229  *
00230  * Author:   Michael Holst
00231  * ***************************************************************************
00232  */
00233 VPUBLIC void *Vmem_malloc(Vmem *thee, size_t num, size_t size)
00234 {
00235     size_t btmp;
00236     void *ram = VNULL;
00237 
00238     Vmem_init();
00239 
00240     /* VWARN( (num > 0) && (size > 0) ); */
00241     VASSERT( (num > 0) && (size > 0) );
00242     if ( (num > 0) && (size > 0) ) {
00243                       
00244         ram = (void*)calloc((size_t)num, (size_t)size);
00245         if (ram == VNULL) {
00246             fprintf(stderr, "Unable to allocate memory!\n");
00247             fprintf(stderr, "(This often means you don't have enough memory available for this calculation.)\n");
00248                                  printf("FATAL ERROR: Unable to allocate enough memory for problem size.\n");
00249                                  printf("FATAL ERROR: You requested %u bytes of RAM.\n",(size_t)num * (size_t)size);
00250                                  printf("FATAL ERROR: Check that your system has that much memory.\n");
00251         }
00252         VASSERT( ram != VNULL );
00253 
00254         vmemTotal.mallocBytes += (num * size);
00255         btmp = (vmemTotal.mallocBytes - vmemTotal.freeBytes);
00256         if ( vmemTotal.highWater < btmp ) vmemTotal.highWater = btmp;
00257         vmemTotal.mallocAreas++;
00258 
00259         if (thee != VNULL) {
00260             thee->mallocBytes += (num * size);
00261             btmp = (thee->mallocBytes - thee->freeBytes);
00262             if ( thee->highWater < btmp ) thee->highWater = btmp;
00263             thee->mallocAreas++;
00264         } else {
00265             vmemMisc.mallocBytes += (num * size);
00266             btmp = (vmemMisc.mallocBytes - vmemMisc.freeBytes);
00267             if ( vmemMisc.highWater < btmp ) vmemMisc.highWater = btmp;
00268             vmemMisc.mallocAreas++;
00269         }
00270 
00271     }
00272 
00273     return ram;
00274 }
00275 
00276 /*
00277  * ***************************************************************************
00278  * Routine:  Vmem_free
00279  *
00280  * Purpose:  A logged version of free.
00281  *
00282  * Author:   Michael Holst
00283  * ***************************************************************************
00284  */
00285 VPUBLIC void Vmem_free(Vmem *thee, size_t num, size_t size, void **ram)
00286 {
00287     Vmem_init();
00288 
00289     /* VWARN( (*ram) != VNULL ); */
00290     VASSERT( (*ram) != VNULL );
00291     if ((*ram) != VNULL) {
00292 
00293         free(*ram);
00294         (*ram) = VNULL;
00295 
00296         vmemTotal.freeBytes += (num * size);
00297         vmemTotal.mallocAreas--;
00298 
00299         if (thee != VNULL) {
00300             thee->freeBytes += (num * size);
00301             thee->mallocAreas--;
00302         } else {
00303             vmemMisc.freeBytes += (num * size);
00304             vmemMisc.mallocAreas--;
00305         }
00306     }
00307 }
00308 
00309 /*
00310  * ***************************************************************************
00311  * Routine:  Vmem_realloc
00312  *
00313  * Purpose:  A logged version of realloc (using this is usually a bad idea).
00314  *
00315  * Author:   Michael Holst
00316  * ***************************************************************************
00317  */
00318 VPUBLIC void *Vmem_realloc(Vmem *thee, size_t num, size_t size, void **ram,
00319     size_t newNum)
00320 {
00321     void *tee = Vmem_malloc(thee, newNum, size);
00322     memcpy(tee, (*ram), size*VMIN2(num,newNum));
00323     Vmem_free(thee, num, size, ram);
00324     return tee;
00325 }
00326 
00327 /*
00328  * ***************************************************************************
00329  * Routine:  Vmem_bytes
00330  *
00331  * Purpose:  Return total of ACTIVE malloc areas used by the Vmem object.
00332  *           (If Vmem is VNULL, return the misc catch-all malloc total).
00333  *
00334  * Author:   Michael Holst
00335  * ***************************************************************************
00336  */
00337 VPUBLIC size_t Vmem_bytes(Vmem *thee)
00338 {
00339     Vmem_init();
00340 
00341     if (thee != VNULL) {
00342         return (thee->mallocBytes - thee->freeBytes);
00343     } else {
00344         return (vmemMisc.mallocBytes - vmemMisc.freeBytes);
00345     }
00346 }
00347 
00348 /*
00349  * ***************************************************************************
00350  * Routine:  Vmem_mallocBytes
00351  *
00352  * Purpose:  Return total of all mallocs performed by the Vmem object.
00353  *           (If Vmem is VNULL, return the misc catch-all malloc total).
00354  *
00355  * Author:   Michael Holst
00356  * ***************************************************************************
00357  */
00358 VPUBLIC size_t Vmem_mallocBytes(Vmem *thee)
00359 {
00360     Vmem_init();
00361 
00362     if (thee != VNULL) {
00363         return thee->mallocBytes;
00364     } else {
00365         return vmemMisc.mallocBytes;
00366     }
00367 }
00368 
00369 /*
00370  * ***************************************************************************
00371  * Routine:  Vmem_freeBytes
00372  *
00373  * Purpose:  Return total of the frees performed by the Vmem object.
00374  *           (If Vmem is VNULL, return misc catch-all free total).
00375  *
00376  * Author:   Michael Holst
00377  * ***************************************************************************
00378  */
00379 VPUBLIC size_t Vmem_freeBytes(Vmem *thee)
00380 {
00381     Vmem_init();
00382 
00383     if (thee != VNULL) {
00384         return thee->freeBytes;
00385     } else {
00386         return vmemMisc.freeBytes;
00387     }
00388 }
00389 
00390 /*
00391  * ***************************************************************************
00392  * Routine:  Vmem_highWater
00393  *
00394  * Purpose:  Return the high-water malloc bytemark hit by the Vmem object.
00395  *           (If Vmem is VNULL, return misc catch-all malloc highwater).
00396  *
00397  * Author:   Michael Holst
00398  * ***************************************************************************
00399  */
00400 VPUBLIC size_t Vmem_highWater(Vmem *thee)
00401 {
00402     Vmem_init();
00403 
00404     if (thee != VNULL) {
00405         return thee->highWater;
00406     } else {
00407         return vmemMisc.highWater;
00408     }
00409 }
00410 
00411 /*
00412  * ***************************************************************************
00413  * Routine:  Vmem_mallocAreas
00414  *
00415  * Purpose:  Return the total number of individual active malloc areas.
00416  *           (If Vmem is VNULL, return misc catch-all malloc areas).
00417  *
00418  * Author:   Michael Holst
00419  * ***************************************************************************
00420  */
00421 VPUBLIC size_t Vmem_mallocAreas(Vmem *thee)
00422 {
00423     Vmem_init();
00424 
00425     if (thee != VNULL) {
00426         return thee->mallocAreas;
00427     } else {
00428         return vmemMisc.mallocAreas;
00429     }
00430 }
00431 
00432 /*
00433  * ***************************************************************************
00434  * Routine:  Vmem_print
00435  *
00436  * Purpose:  Print current memory statistics associated with this Vmem object.
00437  *           (If Vmem is VNULL, print info for the catch-all ovject).
00438  *
00439  * Author:   Michael Holst
00440  * ***************************************************************************
00441  */
00442 VPUBLIC void Vmem_print(Vmem *thee)
00443 {
00444     Vmem_init();
00445 
00446     if (thee != VNULL) {
00447         fprintf(stderr,"%12ld %12ld %12ld %12ld %12ld %% %s\n",
00448             (thee->mallocBytes-thee->freeBytes),
00449             thee->mallocAreas, thee->mallocBytes,
00450             thee->freeBytes, thee->highWater,
00451             thee->name);
00452     } else {
00453         fprintf(stderr,"%12ld %12ld %12ld %12ld %12ld %% %s\n",
00454             (vmemMisc.mallocBytes-vmemMisc.freeBytes),
00455             vmemMisc.mallocAreas, vmemMisc.mallocBytes,
00456             vmemMisc.freeBytes, vmemMisc.highWater,
00457             vmemMisc.name);
00458     }
00459 }
00460 

Generated on Wed Oct 20 2010 11:12:15 for APBS by  doxygen 1.7.2