home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 22 gnu / 22-gnu.zip / mesch12a.zip / memstat.c < prev    next >
C/C++ Source or Header  |  1994-01-13  |  9KB  |  384 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. /*  mem_stat.c    6/09/93  */
  28.  
  29. /* Deallocation of static arrays */
  30.  
  31.  
  32. #include <stdio.h>
  33. #include  "matrix.h"
  34. #include  "meminfo.h"
  35. #ifdef COMPLEX   
  36. #include  "zmatrix.h"
  37. #endif
  38. #ifdef SPARSE
  39. #include  "sparse.h"
  40. #include  "iter.h"
  41. #endif
  42.  
  43. static char rcsid[] = "$Id: memstat.c,v 1.1 1994/01/13 05:32:44 des Exp $";
  44.  
  45. /* global variable */
  46.  
  47. extern MEM_CONNECT mem_connect[MEM_CONNECT_MAX_LISTS];
  48.  
  49.  
  50. /* local type */
  51.  
  52. typedef struct {
  53.    void **var;    /* for &A, where A is a pointer */
  54.    int type;     /* type of A */
  55.    int mark;      /* what mark is chosen */
  56. } MEM_STAT_STRUCT;
  57.  
  58.  
  59. /* local variables */
  60.  
  61. /* how many marks are used */
  62. static int mem_stat_mark_many = 0;
  63.  
  64. /* current mark */
  65. static int mem_stat_mark_curr = 0;
  66.  
  67.  
  68. static MEM_STAT_STRUCT mem_stat_var[MEM_HASHSIZE];
  69.  
  70. /* array of indices (+1) to mem_stat_var */
  71. static unsigned int mem_hash_idx[MEM_HASHSIZE];
  72.  
  73. /* points to the first unused element in mem_hash_idx */
  74. static unsigned int mem_hash_idx_end = 0;
  75.  
  76.  
  77.  
  78. /* hashing function */
  79.  
  80. static unsigned int mem_hash(ptr)
  81. void **ptr;
  82. {
  83.    unsigned long lp = (unsigned long)ptr;
  84.  
  85.    return (lp % MEM_HASHSIZE);
  86. }
  87.  
  88.  
  89. /* look for a place in mem_stat_var */
  90. static int mem_lookup(var)
  91. void **var;
  92. {
  93.    int k, j;
  94.  
  95.    k = mem_hash(var);
  96.  
  97.    if (mem_stat_var[k].var == var) {
  98.       return -1;
  99.    }
  100.    else if (mem_stat_var[k].var == NULL) {
  101.       return k;
  102.    }
  103.    else {  /* look for an empty place */
  104.       j = k;
  105.       while (mem_stat_var[j].var != var && j < MEM_HASHSIZE
  106.          && mem_stat_var[j].var != NULL) 
  107.     j++;
  108.  
  109.       if (mem_stat_var[j].var == NULL) return j;
  110.       else if (mem_stat_var[j].var == var) return -1; 
  111.       else { /* if (j == MEM_HASHSIZE) */
  112.      j = 0;
  113.      while (mem_stat_var[j].var != var && j < k
  114.         && mem_stat_var[j].var != NULL) 
  115.        j++;
  116.      if (mem_stat_var[j].var == NULL) return j;
  117.      else if (mem_stat_var[j].var == var) return -1; 
  118.      else { /* if (j == k) */
  119.         fprintf(stderr,
  120.               "\n WARNING !!! static memory: mem_stat_var is too small\n");
  121.         fprintf(stderr,
  122.           " Increase MEM_HASHSIZE in file: %s (currently = %d)\n\n",
  123.             MEM_HASHSIZE_FILE, MEM_HASHSIZE);
  124.         if ( !isatty(fileno(stdout)) ) {
  125.            fprintf(stdout,
  126.                 "\n WARNING !!! static memory: mem_stat_var is too small\n");
  127.            fprintf(stdout,
  128.             " Increase MEM_HASHSIZE in file: %s (currently = %d)\n\n",
  129.             MEM_HASHSIZE_FILE, MEM_HASHSIZE);
  130.         }
  131.         error(E_MEM,"mem_lookup");
  132.      }
  133.       }
  134.    }
  135.  
  136.    return -1;
  137. }
  138.  
  139.  
  140. /* register static variables;
  141.    Input arguments:
  142.      var - variable to be registered,
  143.      type - type of this variable; 
  144.      list - list of types
  145.  
  146.    returned value < 0  --> error,
  147.    returned value == 0 --> not registered,
  148.    returned value >= 0 --> registered with this mark;
  149. */
  150.  
  151. int mem_stat_reg_list(var,type,list)
  152. void **var;
  153. int type,list;
  154. {
  155.    int n;
  156.  
  157.    if ( list < 0 || list >= MEM_CONNECT_MAX_LISTS )
  158.      return -1;
  159.  
  160.    if (mem_stat_mark_curr == 0) return 0;  /* not registered */
  161.    if (var == NULL) return -1;             /* error */
  162.  
  163.    if ( type < 0 || type >= mem_connect[list].ntypes || 
  164.        mem_connect[list].free_funcs[type] == NULL )
  165.    {
  166.       warning(WARN_WRONG_TYPE,"mem_stat_reg_list");
  167.       return -1;
  168.    }
  169.    
  170.    if ((n = mem_lookup(var)) >= 0) {
  171.       mem_stat_var[n].var = var;
  172.       mem_stat_var[n].mark = mem_stat_mark_curr;
  173.       mem_stat_var[n].type = type;
  174.       /* save n+1, not n */
  175.       mem_hash_idx[mem_hash_idx_end++] = n+1;
  176.    }
  177.  
  178.    return mem_stat_mark_curr;
  179. }
  180.  
  181.  
  182. /* set a mark;
  183.    Input argument:
  184.    mark - positive number denoting a mark;
  185.    returned: 
  186.              mark if mark > 0,
  187.              0 if mark == 0,
  188.          -1 if mark is negative.
  189. */
  190.  
  191. int mem_stat_mark(mark)
  192. int mark;
  193. {
  194.    if (mark < 0) {
  195.       mem_stat_mark_curr = 0;
  196.       return -1;   /* error */
  197.    }
  198.    else if (mark == 0) {
  199.       mem_stat_mark_curr = 0; 
  200.       return 0; 
  201.    }
  202.  
  203.    mem_stat_mark_curr = mark;
  204.    mem_stat_mark_many++;
  205.  
  206.    return mark;
  207. }
  208.  
  209.  
  210.  
  211. /* deallocate static variables;
  212.    Input argument:
  213.    mark - a positive number denoting the mark;
  214.  
  215.    Returned:
  216.      -1 if mark < 0 (error);
  217.      0  if mark == 0;
  218. */
  219.  
  220. int mem_stat_free_list(mark,list)
  221. int mark,list;
  222. {
  223.    u_int i,j;
  224.    int     (*free_fn)();
  225.  
  226.    if ( list < 0 || list >= MEM_CONNECT_MAX_LISTS 
  227.        || mem_connect[list].free_funcs == NULL )
  228.      return -1;
  229.  
  230.    if (mark < 0) {
  231.       mem_stat_mark_curr = 0;
  232.       return -1;
  233.    }
  234.    else if (mark == 0) {
  235.       mem_stat_mark_curr = 0;
  236.       return 0;
  237.    }
  238.    
  239.    if (mem_stat_mark_many <= 0) {
  240.       warning(WARN_NO_MARK,"mem_stat_free");
  241.       return -1;
  242.    }
  243.  
  244.    /* deallocate the marked variables */
  245.    for (i=0; i < mem_hash_idx_end; i++) {
  246.       j = mem_hash_idx[i];
  247.       if (j == 0) continue;
  248.       else {
  249.      j--;
  250.      if (mem_stat_var[j].mark == mark) {
  251.          free_fn = mem_connect[list].free_funcs[mem_stat_var[j].type];
  252.          if ( free_fn != NULL )
  253.          (*free_fn)(*mem_stat_var[j].var);
  254.          else
  255.          warning(WARN_WRONG_TYPE,"mem_stat_free");
  256.         
  257.         *(mem_stat_var[j].var) = NULL;
  258.         mem_stat_var[j].var = NULL;
  259.         mem_stat_var[j].mark = 0;
  260.         mem_hash_idx[i] = 0;
  261.      }
  262.       }
  263.    }
  264.  
  265.    while (mem_hash_idx_end > 0 && mem_hash_idx[mem_hash_idx_end-1] == 0)
  266.      mem_hash_idx_end--;
  267.  
  268.    mem_stat_mark_curr = 0;
  269.    mem_stat_mark_many--;
  270.    return 0;
  271. }
  272.  
  273.  
  274. /* only for diagnostic purposes */
  275.  
  276. void mem_stat_dump(fp,list)
  277. FILE *fp;
  278. int list;
  279. {
  280.    u_int i,j,k=1;
  281.  
  282.    if ( list < 0 || list >= MEM_CONNECT_MAX_LISTS 
  283.        || mem_connect[list].free_funcs == NULL )
  284.      return;
  285.  
  286.    fprintf(fp," Array mem_stat_var (list no. %d):\n",list);
  287.    for (i=0; i < mem_hash_idx_end; i++) {
  288.       j = mem_hash_idx[i];
  289.       if (j == 0) continue;
  290.       else {
  291.      j--;
  292.      fprintf(fp," %d.  var = 0x%p, type = %s, mark = %d\n",
  293.          k,mem_stat_var[j].var,
  294.          mem_stat_var[j].type < mem_connect[list].ntypes &&
  295.          mem_connect[list].free_funcs[mem_stat_var[j].type] != NULL ?
  296.          mem_connect[list].type_names[(int)mem_stat_var[j].type] : 
  297.          "???",
  298.          mem_stat_var[j].mark);
  299.      k++;
  300.       }
  301.    }
  302.    
  303.    fprintf(fp,"\n");
  304. }
  305.  
  306.  
  307. /* query function about the current mark */
  308. #ifdef ANSI_C
  309. int mem_stat_show_mark(void)
  310. #else
  311. int mem_stat_show_mark()
  312. #endif
  313. {
  314.    return mem_stat_mark_curr;
  315. }
  316.  
  317.  
  318. /* Varying number of arguments */
  319.  
  320.  
  321. #ifdef ANSI_C
  322.  
  323. /* To allocate memory to many arguments. 
  324.    The function should be called:
  325.    mem_stat_vars(list,type,&v1,&v2,&v3,...,VNULL);
  326.    where 
  327.      int list,type;
  328.      void **v1, **v2, **v3,...;
  329.      The last argument should be VNULL ! 
  330.      type is the type of variables v1,v2,v3,...
  331.      (of course they must be of the same type)
  332. */
  333.  
  334. int mem_stat_reg_vars(int list,int type,...)
  335. {
  336.    va_list ap;
  337.    int i=0;
  338.    void **par;
  339.    
  340.    va_start(ap, type);
  341.    while (par = va_arg(ap,void **)) {   /* NULL ends the list*/
  342.       mem_stat_reg_list(par,type,list);
  343.       i++;
  344.    } 
  345.  
  346.    va_end(ap);
  347.    return i;
  348. }
  349.  
  350. #elif VARARGS
  351. /* old varargs is used */
  352.  
  353. /* To allocate memory to many arguments. 
  354.    The function should be called:
  355.    mem_stat_vars(list,type,&v1,&v2,&v3,...,VNULL);
  356.    where 
  357.      int list,type;
  358.      void **v1, **v2, **v3,...;
  359.      The last argument should be VNULL ! 
  360.      type is the type of variables v1,v2,v3,...
  361.      (of course they must be of the same type)
  362. */
  363.  
  364. int mem_stat_reg_vars(va_alist) va_dcl
  365. {
  366.    va_list ap;
  367.    int type,list,i=0;
  368.    void **par;
  369.    
  370.    va_start(ap);
  371.    list = va_arg(ap,int);
  372.    type = va_arg(ap,int);
  373.    while (par = va_arg(ap,void **)) {   /* NULL ends the list*/
  374.       mem_stat_reg_list(par,type,list);
  375.       i++;
  376.    } 
  377.  
  378.    va_end(ap);
  379.    return i;
  380. }
  381.  
  382.  
  383. #endif
  384.