home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 22 gnu / 22-gnu.zip / mesch12a.zip / meminfo.c < prev    next >
C/C++ Source or Header  |  1994-01-13  |  10KB  |  392 lines

  1.  
  2. /**************************************************************************
  3. **
  4. ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved.
  5. **
  6. **                 Meschach Library
  7. ** 
  8. ** This Meschach Library is provided "as is" without any express 
  9. ** or implied warranty of any kind with respect to this software. 
  10. ** In particular the authors shall not be liable for any direct, 
  11. ** indirect, special, incidental or consequential damages arising 
  12. ** in any way from use of the software.
  13. ** 
  14. ** Everyone is granted permission to copy, modify and redistribute this
  15. ** Meschach Library, provided:
  16. **  1.  All copies contain this copyright notice.
  17. **  2.  All modified copies shall carry a notice stating who
  18. **      made the last modification and the date of such modification.
  19. **  3.  No charge is made for this software or works derived from it.  
  20. **      This clause shall not be construed as constraining other software
  21. **      distributed on the same medium as this software, nor is a
  22. **      distribution fee considered a charge.
  23. **
  24. ***************************************************************************/
  25.  
  26.  
  27. /* meminfo.c  revised  22/11/93 */
  28.  
  29. /* 
  30.   contains basic functions, types and arrays 
  31.   to keep track of memory allocation/deallocation
  32. */
  33.  
  34. #include <stdio.h>
  35. #include  "matrix.h"
  36. #include  "meminfo.h"
  37. #ifdef COMPLEX   
  38. #include  "zmatrix.h"
  39. #endif
  40. #ifdef SPARSE
  41. #include  "sparse.h"
  42. #include  "iter.h"
  43. #endif
  44.  
  45. static char rcsid[] = "$Id: meminfo.c,v 1.1 1994/01/13 05:31:39 des Exp $";
  46.  
  47. /* this array is defined further in this file */
  48. extern MEM_CONNECT mem_connect[MEM_CONNECT_MAX_LISTS];
  49.  
  50.  
  51. /* names of types */
  52. static char *mem_type_names[] = {
  53.    "MAT",
  54.    "BAND",
  55.    "PERM",
  56.    "VEC",
  57.    "IVEC"
  58. #ifdef SPARSE
  59.      ,"ITER",
  60.      "SPROW",
  61.      "SPMAT"
  62. #endif
  63. #ifdef COMPLEX   
  64.        ,"ZVEC",
  65.        "ZMAT"
  66. #endif
  67.       };
  68.  
  69.  
  70. #define MEM_NUM_STD_TYPES  (sizeof(mem_type_names)/sizeof(mem_type_names[0]))
  71.  
  72.  
  73. /* local array for keeping track of memory */
  74. static MEM_ARRAY   mem_info_sum[MEM_NUM_STD_TYPES];  
  75.  
  76.  
  77. /* for freeing various types */
  78. static int (*mem_free_funcs[MEM_NUM_STD_TYPES])() = {
  79.    m_free,
  80.    bd_free,
  81.    px_free,    
  82.    v_free,    
  83.    iv_free
  84. #ifdef SPARSE
  85.      ,iter_free,    
  86.      sprow_free, 
  87.      sp_free
  88. #endif
  89. #ifdef COMPLEX
  90.        ,zv_free,    
  91.        zm_free
  92. #endif
  93.       };
  94.  
  95.  
  96.  
  97. /* it is a global variable for passing 
  98.    pointers to local arrays defined here */
  99. MEM_CONNECT mem_connect[MEM_CONNECT_MAX_LISTS] = {
  100.  { mem_type_names, mem_free_funcs, MEM_NUM_STD_TYPES, 
  101.      mem_info_sum } 
  102. };
  103.  
  104.  
  105. /* attach a new list of types */
  106.  
  107. int mem_attach_list(list, ntypes, type_names, free_funcs, info_sum)
  108. int list,ntypes;         /* number of a list and number of types there */
  109. char *type_names[];      /* list of names of types */
  110. int (*free_funcs[])();   /* list of releasing functions */
  111. MEM_ARRAY info_sum[];    /* local table */
  112. {
  113.    if (list < 0 || list >= MEM_CONNECT_MAX_LISTS)
  114.      return -1;
  115.  
  116.    if (type_names == NULL || free_funcs == NULL 
  117.        || info_sum == NULL || ntypes < 0)
  118.      return -1;
  119.    
  120.    /* if a list exists do not overwrite */
  121.    if ( mem_connect[list].ntypes != 0 )
  122.      error(E_OVERWRITE,"mem_attach_list");
  123.    
  124.    mem_connect[list].ntypes = ntypes;
  125.    mem_connect[list].type_names = type_names;
  126.    mem_connect[list].free_funcs = free_funcs;
  127.    mem_connect[list].info_sum = info_sum;
  128.    return 0;
  129. }
  130.  
  131.  
  132. /* release a list of types */
  133. int mem_free_vars(list)
  134. int list;
  135. {    
  136.    if (list < 0 || list >= MEM_CONNECT_MAX_LISTS)
  137.      return -1;
  138.    
  139.    mem_connect[list].ntypes = 0;
  140.    mem_connect[list].type_names = NULL;
  141.    mem_connect[list].free_funcs = NULL;
  142.    mem_connect[list].info_sum = NULL;
  143.    
  144.    return 0;
  145. }
  146.  
  147.  
  148.  
  149. /* check if list is attached */
  150.  
  151. int mem_is_list_attached(list)
  152. int list;
  153. {
  154.    if ( list < 0 || list >= MEM_CONNECT_MAX_LISTS )
  155.    return FALSE;
  156.  
  157.    if ( mem_connect[list].type_names != NULL &&
  158.         mem_connect[list].free_funcs != NULL &&
  159.         mem_connect[list].info_sum != NULL)
  160.      return TRUE;
  161.    else return FALSE;
  162. }
  163.  
  164. /* to print out the contents of mem_connect[list] */
  165.  
  166. void mem_dump_list(fp,list)
  167. FILE *fp;
  168. int list;
  169. {
  170.    int i;
  171.    MEM_CONNECT *mlist;
  172.  
  173.    if ( list < 0 || list >= MEM_CONNECT_MAX_LISTS )
  174.      return;
  175.  
  176.    mlist = &mem_connect[list];
  177.    fprintf(fp," %15s[%d]:\n","CONTENTS OF mem_connect",list);
  178.    fprintf(fp," %-7s   %-12s   %-9s   %s\n",
  179.        "name of",
  180.        "alloc.", "# alloc.",
  181.        "address"
  182.        );
  183.    fprintf(fp," %-7s   %-12s   %-9s   %s\n",
  184.        " type",
  185.        "bytes", "variables",
  186.        "of *_free()"
  187.        );
  188.  
  189.    for (i=0; i < mlist->ntypes; i++) 
  190.      fprintf(fp,"  %-7s   %-12ld   %-9d   %p\n",
  191.          mlist->type_names[i], mlist->info_sum[i].bytes,
  192.          mlist->info_sum[i].numvar, mlist->free_funcs[i]
  193.          );
  194.    
  195.    fprintf(fp,"\n");
  196. }
  197.  
  198.  
  199.  
  200. /*=============================================================*/
  201.  
  202.  
  203. /* local variables */
  204.  
  205. static int    mem_switched_on = MEM_SWITCH_ON_DEF;  /* on/off */
  206.  
  207.  
  208. /* switch on/off memory info */
  209.  
  210. int mem_info_on(sw)
  211. int sw;
  212. {
  213.    int old = mem_switched_on;
  214.    
  215.    mem_switched_on = sw;
  216.    return old;
  217. }
  218.  
  219. #ifdef ANSI_C
  220. int mem_info_is_on(void)
  221. #else
  222. int mem_info_is_on()
  223. #endif
  224. {
  225.    return mem_switched_on;
  226. }
  227.  
  228.  
  229. /* information about allocated memory */
  230.  
  231. /* return the number of allocated bytes for type 'type' */
  232.  
  233. long mem_info_bytes(type,list)
  234. int type,list;
  235. {
  236.    if ( list < 0 || list >= MEM_CONNECT_MAX_LISTS )
  237.      return 0l;
  238.    if ( !mem_switched_on || type < 0 
  239.        || type >= mem_connect[list].ntypes
  240.        || mem_connect[list].free_funcs[type] == NULL )
  241.      return 0l;
  242.    
  243.    return mem_connect[list].info_sum[type].bytes;
  244. }
  245.  
  246. /* return the number of allocated variables for type 'type' */
  247. int mem_info_numvar(type,list)
  248. int type,list;
  249. {
  250.    if ( list < 0 || list >= MEM_CONNECT_MAX_LISTS )
  251.      return 0l;
  252.    if ( !mem_switched_on || type < 0 
  253.        || type >= mem_connect[list].ntypes
  254.        || mem_connect[list].free_funcs[type] == NULL )
  255.      return 0l;
  256.    
  257.    return mem_connect[list].info_sum[type].numvar;
  258. }
  259.  
  260.  
  261.  
  262. /* print out memory info to the file fp */
  263. void mem_info_file(fp,list)
  264. FILE *fp;
  265. int list;
  266. {
  267.    unsigned int type;
  268.    long t = 0l, d;
  269.    int n = 0, nt = 0;
  270.    MEM_CONNECT *mlist;
  271.    
  272.    if (!mem_switched_on) return;
  273.    if ( list < 0 || list >= MEM_CONNECT_MAX_LISTS )
  274.      return;
  275.    
  276.    if (list == 0)
  277.      fprintf(fp," MEMORY INFORMATION (standard types):\n");
  278.    else
  279.      fprintf(fp," MEMORY INFORMATION (list no. %d):\n",list);
  280.  
  281.    mlist = &mem_connect[list];
  282.  
  283.    for (type=0; type < mlist->ntypes; type++) {
  284.       if (mlist->type_names[type] == NULL ) continue;
  285.       d = mlist->info_sum[type].bytes;
  286.       t += d;
  287.       n = mlist->info_sum[type].numvar;
  288.       nt += n;
  289.       fprintf(fp," type %-7s %10ld alloc. byte%c  %6d alloc. variable%c\n",
  290.           mlist->type_names[type], d, (d!=1 ? 's' : ' '),
  291.           n, (n!=1 ? 's' : ' '));
  292.    }
  293.  
  294.    fprintf(fp," %-12s %10ld alloc. byte%c  %6d alloc. variable%c\n\n",
  295.        "total:",t, (t!=1 ? 's' : ' '),
  296.        nt, (nt!=1 ? 's' : ' '));
  297. }
  298.  
  299.  
  300. /* function for memory information */
  301.  
  302.  
  303. /* mem_bytes_list
  304.    
  305.    Arguments:
  306.    type - the number of type;
  307.    old_size - old size of allocated memory (in bytes);
  308.    new_size - new size of allocated memory (in bytes);
  309.    list - list of types
  310.    */
  311.  
  312.  
  313. void mem_bytes_list(type,old_size,new_size,list)
  314. int type,list;
  315. int old_size,new_size;
  316. {
  317.    MEM_CONNECT *mlist;
  318.    
  319.    if ( list < 0 || list >= MEM_CONNECT_MAX_LISTS )
  320.      return;
  321.    
  322.    mlist = &mem_connect[list];
  323.    if (  type < 0 || type >= mlist->ntypes
  324.        || mlist->free_funcs[type] == NULL )
  325.      return;
  326.  
  327.    if ( old_size < 0 || new_size < 0 )
  328.      error(E_NEG,"mem_bytes_list");
  329.  
  330.    mlist->info_sum[type].bytes += new_size - old_size;
  331.    
  332.    /* check if the number of bytes is non-negative */
  333.    if ( old_size > 0 ) {
  334.  
  335.       if (mlist->info_sum[type].bytes < 0)
  336.       {
  337.      fprintf(stderr,
  338.        "\n WARNING !! memory info: allocated memory is less than 0\n");
  339.      fprintf(stderr,"\t TYPE %s \n\n", mlist->type_names[type]);
  340.  
  341.      if ( !isatty(fileno(stdout)) ) {
  342.         fprintf(stdout,
  343.           "\n WARNING !! memory info: allocated memory is less than 0\n");
  344.         fprintf(stdout,"\t TYPE %s \n\n", mlist->type_names[type]);
  345.      }
  346.       }
  347.    }
  348. }
  349.  
  350.  
  351. /* mem_numvar_list
  352.    
  353.    Arguments:
  354.    type - the number of type;
  355.    num - # of variables allocated (> 0) or deallocated ( < 0)
  356.    list - list of types
  357.    */
  358.  
  359.  
  360. void mem_numvar_list(type,num,list)
  361. int type,list,num;
  362. {
  363.    MEM_CONNECT *mlist;
  364.    
  365.    if ( list < 0 || list >= MEM_CONNECT_MAX_LISTS )
  366.      return;
  367.    
  368.    mlist = &mem_connect[list];
  369.    if (  type < 0 || type >= mlist->ntypes
  370.        || mlist->free_funcs[type] == NULL )
  371.      return;
  372.  
  373.    mlist->info_sum[type].numvar += num;
  374.    
  375.    /* check if the number of variables is non-negative */
  376.    if ( num < 0 ) {
  377.  
  378.       if (mlist->info_sum[type].numvar < 0)
  379.       {
  380.      fprintf(stderr,
  381.        "\n WARNING !! memory info: allocated # of variables is less than 0\n");
  382.      fprintf(stderr,"\t TYPE %s \n\n", mlist->type_names[type]);
  383.      if ( !isatty(fileno(stdout)) ) {
  384.         fprintf(stdout,
  385.       "\n WARNING !! memory info: allocated # of variables is less than 0\n");
  386.         fprintf(stdout,"\t TYPE %s \n\n", mlist->type_names[type]);
  387.      }
  388.       }
  389.    }
  390. }
  391.  
  392.