memstat.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  1. /**************************************************************************
  2. **
  3. ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved.
  4. **
  5. ** Meschach Library
  6. **
  7. ** This Meschach Library is provided "as is" without any express
  8. ** or implied warranty of any kind with respect to this software.
  9. ** In particular the authors shall not be liable for any direct,
  10. ** indirect, special, incidental or consequential damages arising
  11. ** in any way from use of the software.
  12. **
  13. ** Everyone is granted permission to copy, modify and redistribute this
  14. ** Meschach Library, provided:
  15. ** 1. All copies contain this copyright notice.
  16. ** 2. All modified copies shall carry a notice stating who
  17. ** made the last modification and the date of such modification.
  18. ** 3. No charge is made for this software or works derived from it.
  19. ** This clause shall not be construed as constraining other software
  20. ** distributed on the same medium as this software, nor is a
  21. ** distribution fee considered a charge.
  22. **
  23. ***************************************************************************/
  24. /* mem_stat.c 6/09/93 */
  25. /* Deallocation of static arrays */
  26. #include <stdio.h>
  27. #include "matrix.h"
  28. #include "meminfo.h"
  29. #ifdef COMPLEX
  30. #include "zmatrix.h"
  31. #endif
  32. #ifdef SPARSE
  33. #include "sparse.h"
  34. #include "iter.h"
  35. #endif
  36. static char rcsid[] = "$Id: memstat.c,v 1.1 1994/01/13 05:32:44 des Exp $";
  37. /* global variable */
  38. extern MEM_CONNECT mem_connect[MEM_CONNECT_MAX_LISTS];
  39. /* local type */
  40. typedef struct {
  41. void **var; /* for &A, where A is a pointer */
  42. int type; /* type of A */
  43. int mark; /* what mark is chosen */
  44. char *fname; /* source file name where last registered */
  45. int line; /* line # of file where last registered */
  46. } MEM_STAT_STRUCT;
  47. /* local variables */
  48. /* how many marks are used */
  49. static int mem_stat_mark_many = 0;
  50. /* current mark */
  51. static int mem_stat_mark_curr = 0;
  52. static MEM_STAT_STRUCT mem_stat_var[MEM_HASHSIZE];
  53. /* array of indices (+1) to mem_stat_var */
  54. static unsigned int mem_hash_idx[MEM_HASHSIZE];
  55. /* points to the first unused element in mem_hash_idx */
  56. static unsigned int mem_hash_idx_end = 0;
  57. /* hashing function */
  58. #ifndef ANSI_C
  59. static unsigned int mem_hash(ptr)
  60. void **ptr;
  61. #else
  62. static unsigned int mem_hash(void **ptr)
  63. #endif
  64. {
  65. unsigned long lp = (unsigned long)ptr;
  66. return (lp % MEM_HASHSIZE);
  67. }
  68. /* look for a place in mem_stat_var */
  69. #ifndef ANSI_C
  70. static int mem_lookup(var)
  71. void **var;
  72. #else
  73. static int mem_lookup(void **var)
  74. #endif
  75. {
  76. int k, j;
  77. k = mem_hash(var);
  78. if (mem_stat_var[k].var == var) {
  79. return -1;
  80. }
  81. else if (mem_stat_var[k].var == NULL) {
  82. return k;
  83. }
  84. else { /* look for an empty place */
  85. j = k;
  86. while (mem_stat_var[j].var != var && j < MEM_HASHSIZE
  87. && mem_stat_var[j].var != NULL)
  88. j++;
  89. if (mem_stat_var[j].var == NULL) return j;
  90. else if (mem_stat_var[j].var == var) return -1;
  91. else { /* if (j == MEM_HASHSIZE) */
  92. j = 0;
  93. while (mem_stat_var[j].var != var && j < k
  94. && mem_stat_var[j].var != NULL)
  95. j++;
  96. if (mem_stat_var[j].var == NULL) return j;
  97. else if (mem_stat_var[j].var == var) return -1;
  98. else { /* if (j == k) */
  99. fprintf(stderr,
  100. "\n WARNING !!! static memory: mem_stat_var is too small\n");
  101. fprintf(stderr,
  102. " Increase MEM_HASHSIZE in file: %s (currently = %d)\n\n",
  103. MEM_HASHSIZE_FILE, MEM_HASHSIZE);
  104. if ( !isatty(fileno(stdout)) ) {
  105. fprintf(stdout,
  106. "\n WARNING !!! static memory: mem_stat_var is too small\n");
  107. fprintf(stdout,
  108. " Increase MEM_HASHSIZE in file: %s (currently = %d)\n\n",
  109. MEM_HASHSIZE_FILE, MEM_HASHSIZE);
  110. }
  111. error(E_MEM,"mem_lookup");
  112. }
  113. }
  114. }
  115. return -1;
  116. }
  117. /* register static variables;
  118. Input arguments:
  119. var - variable to be registered,
  120. type - type of this variable;
  121. list - list of types
  122. fname - source file name where last registered
  123. line - line number of source file
  124. returned value < 0 --> error,
  125. returned value == 0 --> not registered,
  126. returned value >= 0 --> registered with this mark;
  127. */
  128. #ifndef ANSI_C
  129. int mem_stat_reg_list(var,type,list,fname,line)
  130. void **var;
  131. int type,list;
  132. char *fname;
  133. int line;
  134. #else
  135. int mem_stat_reg_list(void **var, int type, int list,
  136. char *fname, int line)
  137. #endif
  138. {
  139. int n;
  140. if ( list < 0 || list >= MEM_CONNECT_MAX_LISTS )
  141. return -1;
  142. if (mem_stat_mark_curr == 0) return 0; /* not registered */
  143. if (var == NULL) return -1; /* error */
  144. if ( type < 0 || type >= mem_connect[list].ntypes ||
  145. mem_connect[list].free_funcs[type] == NULL )
  146. {
  147. warning(WARN_WRONG_TYPE,"mem_stat_reg_list");
  148. return -1;
  149. }
  150. if ((n = mem_lookup(var)) >= 0) {
  151. mem_stat_var[n].var = var;
  152. mem_stat_var[n].mark = mem_stat_mark_curr;
  153. mem_stat_var[n].type = type;
  154. mem_stat_var[n].fname = fname;
  155. mem_stat_var[n].line = line;
  156. /* save n+1, not n */
  157. mem_hash_idx[mem_hash_idx_end++] = n+1;
  158. }
  159. return mem_stat_mark_curr;
  160. }
  161. /* set a mark;
  162. Input argument:
  163. mark - positive number denoting a mark;
  164. returned:
  165. mark if mark > 0,
  166. 0 if mark == 0,
  167. -1 if mark is negative.
  168. */
  169. #ifndef ANSI_C
  170. int mem_stat_mark(mark)
  171. int mark;
  172. #else
  173. int mem_stat_mark(int mark)
  174. #endif
  175. {
  176. if (mark < 0) {
  177. mem_stat_mark_curr = 0;
  178. return -1; /* error */
  179. }
  180. else if (mark == 0) {
  181. mem_stat_mark_curr = 0;
  182. return 0;
  183. }
  184. mem_stat_mark_curr = mark;
  185. mem_stat_mark_many++;
  186. return mark;
  187. }
  188. /* deallocate static variables;
  189. Input argument:
  190. mark - a positive number denoting the mark;
  191. Returned:
  192. -1 if mark < 0 (error);
  193. 0 if mark == 0;
  194. */
  195. #ifndef ANSI_C
  196. int mem_stat_free_list(mark,list)
  197. int mark,list;
  198. #else
  199. int mem_stat_free_list(int mark, int list)
  200. #endif
  201. {
  202. unsigned int i,j;
  203. int (*free_fn)();
  204. if ( list < 0 || list >= MEM_CONNECT_MAX_LISTS
  205. || mem_connect[list].free_funcs == NULL )
  206. return -1;
  207. if (mark < 0) {
  208. mem_stat_mark_curr = 0;
  209. return -1;
  210. }
  211. else if (mark == 0) {
  212. mem_stat_mark_curr = 0;
  213. return 0;
  214. }
  215. if (mem_stat_mark_many <= 0) {
  216. warning(WARN_NO_MARK,"mem_stat_free");
  217. return -1;
  218. }
  219. #ifdef DEBUG
  220. printf("mem_stat_free: Freeing variables registered for mark %d\n", mark);
  221. #endif /* DEBUG */
  222. /* deallocate the marked variables */
  223. for (i=0; i < mem_hash_idx_end; i++) {
  224. j = mem_hash_idx[i];
  225. if (j == 0) continue;
  226. else {
  227. j--;
  228. if (mem_stat_var[j].mark == mark) {
  229. free_fn = mem_connect[list].free_funcs[mem_stat_var[j].type];
  230. #ifdef DEBUG
  231. printf("# Freeing variable(s) registered in file \"%s\", line %d\n",
  232. mem_stat_var[j].fname, mem_stat_var[j].line);
  233. #endif /* DEBUG */
  234. if ( free_fn != NULL )
  235. (*free_fn)(*mem_stat_var[j].var);
  236. else
  237. warning(WARN_WRONG_TYPE,"mem_stat_free");
  238. *(mem_stat_var[j].var) = NULL;
  239. mem_stat_var[j].var = NULL;
  240. mem_stat_var[j].mark = 0;
  241. mem_stat_var[j].fname = NULL;
  242. mem_stat_var[j].line = 0;
  243. mem_hash_idx[i] = 0;
  244. }
  245. }
  246. }
  247. while (mem_hash_idx_end > 0 && mem_hash_idx[mem_hash_idx_end-1] == 0)
  248. mem_hash_idx_end--;
  249. mem_stat_mark_curr = 0;
  250. mem_stat_mark_many--;
  251. return 0;
  252. }
  253. /* only for diagnostic purposes */
  254. #ifndef ANSI_C
  255. void mem_stat_dump(fp,list)
  256. FILE *fp;
  257. int list;
  258. #else
  259. void mem_stat_dump(FILE *fp, int list)
  260. #endif
  261. {
  262. unsigned int i,j,k=1;
  263. if ( list < 0 || list >= MEM_CONNECT_MAX_LISTS
  264. || mem_connect[list].free_funcs == NULL )
  265. return;
  266. fprintf(fp," Array mem_stat_var (list no. %d):\n",list);
  267. for (i=0; i < mem_hash_idx_end; i++) {
  268. j = mem_hash_idx[i];
  269. if (j == 0) continue;
  270. else {
  271. j--;
  272. fprintf(fp," %d. var = 0x%p, type = %s, mark = %d\n",
  273. k,mem_stat_var[j].var,
  274. mem_stat_var[j].type < mem_connect[list].ntypes &&
  275. mem_connect[list].free_funcs[mem_stat_var[j].type] != NULL ?
  276. mem_connect[list].type_names[(int)mem_stat_var[j].type] :
  277. "???",
  278. mem_stat_var[j].mark);
  279. k++;
  280. }
  281. }
  282. fprintf(fp,"\n");
  283. }
  284. /* query function about the current mark */
  285. #ifdef ANSI_C
  286. int mem_stat_show_mark(void)
  287. #else
  288. int mem_stat_show_mark()
  289. #endif
  290. {
  291. return mem_stat_mark_curr;
  292. }
  293. /* Varying number of arguments */
  294. #ifdef ANSI_C
  295. /* To allocate memory to many arguments.
  296. The function should be called:
  297. mem_stat_vars(list,type,&v1,&v2,&v3,...,VNULL);
  298. where
  299. int list,type;
  300. void **v1, **v2, **v3,...;
  301. The last argument should be VNULL !
  302. type is the type of variables v1,v2,v3,...
  303. (of course they must be of the same type)
  304. */
  305. int mem_stat_reg_vars(int list,int type,char *fname,int line, ...)
  306. {
  307. va_list ap;
  308. int i=0;
  309. void **par;
  310. /* va_start(ap, type); */
  311. va_start(ap,line); /* Changed for Linux 7th Oct, 2003 */
  312. while (par = va_arg(ap,void **)) { /* NULL ends the list*/
  313. mem_stat_reg_list(par,type,list,fname,line);
  314. i++;
  315. }
  316. va_end(ap);
  317. return i;
  318. }
  319. #elif VARARGS
  320. /* old varargs is used */
  321. /* To allocate memory to many arguments.
  322. The function should be called:
  323. mem_stat_vars(list,type,&v1,&v2,&v3,...,VNULL);
  324. where
  325. int list,type;
  326. void **v1, **v2, **v3,...;
  327. The last argument should be VNULL !
  328. type is the type of variables v1,v2,v3,...
  329. (of course they must be of the same type)
  330. */
  331. int mem_stat_reg_vars(va_alist) va_dcl
  332. {
  333. va_list ap;
  334. int type,list,i=0;
  335. void **par;
  336. va_start(ap);
  337. list = va_arg(ap,int);
  338. type = va_arg(ap,int);
  339. while (par = va_arg(ap,void **)) { /* NULL ends the list*/
  340. mem_stat_reg_list(par,type,list);
  341. i++;
  342. }
  343. va_end(ap);
  344. return i;
  345. }
  346. #endif