PageRenderTime 51ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/src/mesch/memstat.c

https://bitbucket.org/nrnhines/nrn
C | 384 lines | 220 code | 78 blank | 86 comment | 75 complexity | acc3fc8f96ff22d76f7f430521b64f09 MD5 | raw file
Possible License(s): BSD-3-Clause, GPL-2.0
  1. #include <../../nrnconf.h>
  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. /* mem_stat.c 6/09/93 */
  26. /* Deallocation of static arrays */
  27. #include <stdio.h>
  28. #include "matrix.h"
  29. #include "meminfo.h"
  30. #ifdef COMPLEX
  31. #include "zmatrix.h"
  32. #endif
  33. #ifdef SPARSE
  34. #include "sparse.h"
  35. #include "iter.h"
  36. #endif
  37. static char rcsid[] = "memstat.c,v 1.1 1997/12/04 17:55:39 hines Exp";
  38. /* global variable */
  39. extern MEM_CONNECT mem_connect[MEM_CONNECT_MAX_LISTS];
  40. /* local type */
  41. typedef struct {
  42. void **var; /* for &A, where A is a pointer */
  43. int type; /* type of A */
  44. int mark; /* what mark is chosen */
  45. } MEM_STAT_STRUCT;
  46. /* local variables */
  47. /* how many marks are used */
  48. static int mem_stat_mark_many = 0;
  49. /* current mark */
  50. static int mem_stat_mark_curr = 0;
  51. static MEM_STAT_STRUCT mem_stat_var[MEM_HASHSIZE];
  52. /* array of indices (+1) to mem_stat_var */
  53. static unsigned int mem_hash_idx[MEM_HASHSIZE];
  54. /* points to the first unused element in mem_hash_idx */
  55. static unsigned int mem_hash_idx_end = 0;
  56. /* hashing function */
  57. static unsigned int mem_hash(ptr)
  58. void **ptr;
  59. {
  60. unsigned long lp = (size_t)ptr;
  61. return (lp % MEM_HASHSIZE);
  62. }
  63. /* look for a place in mem_stat_var */
  64. static int mem_lookup(var)
  65. void **var;
  66. {
  67. int k, j;
  68. k = mem_hash(var);
  69. if (mem_stat_var[k].var == var) {
  70. return -1;
  71. }
  72. else if (mem_stat_var[k].var == NULL) {
  73. return k;
  74. }
  75. else { /* look for an empty place */
  76. j = k;
  77. while (mem_stat_var[j].var != var && j < MEM_HASHSIZE
  78. && mem_stat_var[j].var != NULL)
  79. j++;
  80. if (mem_stat_var[j].var == NULL) return j;
  81. else if (mem_stat_var[j].var == var) return -1;
  82. else { /* if (j == MEM_HASHSIZE) */
  83. j = 0;
  84. while (mem_stat_var[j].var != var && j < k
  85. && mem_stat_var[j].var != NULL)
  86. j++;
  87. if (mem_stat_var[j].var == NULL) return j;
  88. else if (mem_stat_var[j].var == var) return -1;
  89. else { /* if (j == k) */
  90. fprintf(stderr,
  91. "\n WARNING !!! static memory: mem_stat_var is too small\n");
  92. fprintf(stderr,
  93. " Increase MEM_HASHSIZE in file: %s (currently = %d)\n\n",
  94. MEM_HASHSIZE_FILE, MEM_HASHSIZE);
  95. if ( !isatty(fileno(stdout)) ) {
  96. fprintf(stdout,
  97. "\n WARNING !!! static memory: mem_stat_var is too small\n");
  98. fprintf(stdout,
  99. " Increase MEM_HASHSIZE in file: %s (currently = %d)\n\n",
  100. MEM_HASHSIZE_FILE, MEM_HASHSIZE);
  101. }
  102. error(E_MEM,"mem_lookup");
  103. }
  104. }
  105. }
  106. return -1;
  107. }
  108. /* register static variables;
  109. Input arguments:
  110. var - variable to be registered,
  111. type - type of this variable;
  112. list - list of types
  113. returned value < 0 --> error,
  114. returned value == 0 --> not registered,
  115. returned value >= 0 --> registered with this mark;
  116. */
  117. int mem_stat_reg_list(var,type,list)
  118. void **var;
  119. int type,list;
  120. {
  121. int n;
  122. if ( list < 0 || list >= MEM_CONNECT_MAX_LISTS )
  123. return -1;
  124. if (mem_stat_mark_curr == 0) return 0; /* not registered */
  125. if (var == NULL) return -1; /* error */
  126. if ( type < 0 || type >= mem_connect[list].ntypes ||
  127. mem_connect[list].free_funcs[type] == NULL )
  128. {
  129. warning(WARN_WRONG_TYPE,"mem_stat_reg_list");
  130. return -1;
  131. }
  132. if ((n = mem_lookup(var)) >= 0) {
  133. mem_stat_var[n].var = var;
  134. mem_stat_var[n].mark = mem_stat_mark_curr;
  135. mem_stat_var[n].type = type;
  136. /* save n+1, not n */
  137. mem_hash_idx[mem_hash_idx_end++] = n+1;
  138. }
  139. return mem_stat_mark_curr;
  140. }
  141. /* set a mark;
  142. Input argument:
  143. mark - positive number denoting a mark;
  144. returned:
  145. mark if mark > 0,
  146. 0 if mark == 0,
  147. -1 if mark is negative.
  148. */
  149. int mem_stat_mark(mark)
  150. int mark;
  151. {
  152. if (mark < 0) {
  153. mem_stat_mark_curr = 0;
  154. return -1; /* error */
  155. }
  156. else if (mark == 0) {
  157. mem_stat_mark_curr = 0;
  158. return 0;
  159. }
  160. mem_stat_mark_curr = mark;
  161. mem_stat_mark_many++;
  162. return mark;
  163. }
  164. /* deallocate static variables;
  165. Input argument:
  166. mark - a positive number denoting the mark;
  167. Returned:
  168. -1 if mark < 0 (error);
  169. 0 if mark == 0;
  170. */
  171. int mem_stat_free_list(mark,list)
  172. int mark,list;
  173. {
  174. u_int i,j;
  175. int (*free_fn)();
  176. if ( list < 0 || list >= MEM_CONNECT_MAX_LISTS
  177. || mem_connect[list].free_funcs == NULL )
  178. return -1;
  179. if (mark < 0) {
  180. mem_stat_mark_curr = 0;
  181. return -1;
  182. }
  183. else if (mark == 0) {
  184. mem_stat_mark_curr = 0;
  185. return 0;
  186. }
  187. if (mem_stat_mark_many <= 0) {
  188. warning(WARN_NO_MARK,"mem_stat_free");
  189. return -1;
  190. }
  191. /* deallocate the marked variables */
  192. for (i=0; i < mem_hash_idx_end; i++) {
  193. j = mem_hash_idx[i];
  194. if (j == 0) continue;
  195. else {
  196. j--;
  197. if (mem_stat_var[j].mark == mark) {
  198. free_fn = mem_connect[list].free_funcs[mem_stat_var[j].type];
  199. if ( free_fn != NULL )
  200. (*free_fn)(*mem_stat_var[j].var);
  201. else
  202. warning(WARN_WRONG_TYPE,"mem_stat_free");
  203. *(mem_stat_var[j].var) = NULL;
  204. mem_stat_var[j].var = NULL;
  205. mem_stat_var[j].mark = 0;
  206. mem_hash_idx[i] = 0;
  207. }
  208. }
  209. }
  210. while (mem_hash_idx_end > 0 && mem_hash_idx[mem_hash_idx_end-1] == 0)
  211. mem_hash_idx_end--;
  212. mem_stat_mark_curr = 0;
  213. mem_stat_mark_many--;
  214. return 0;
  215. }
  216. /* only for diagnostic purposes */
  217. void mem_stat_dump(fp,list)
  218. FILE *fp;
  219. int list;
  220. {
  221. u_int i,j,k=1;
  222. if ( list < 0 || list >= MEM_CONNECT_MAX_LISTS
  223. || mem_connect[list].free_funcs == NULL )
  224. return;
  225. fprintf(fp," Array mem_stat_var (list no. %d):\n",list);
  226. for (i=0; i < mem_hash_idx_end; i++) {
  227. j = mem_hash_idx[i];
  228. if (j == 0) continue;
  229. else {
  230. j--;
  231. fprintf(fp," %d. var = 0x%p, type = %s, mark = %d\n",
  232. k,mem_stat_var[j].var,
  233. mem_stat_var[j].type < mem_connect[list].ntypes &&
  234. mem_connect[list].free_funcs[mem_stat_var[j].type] != NULL ?
  235. mem_connect[list].type_names[(int)mem_stat_var[j].type] :
  236. "???",
  237. mem_stat_var[j].mark);
  238. k++;
  239. }
  240. }
  241. fprintf(fp,"\n");
  242. }
  243. /* query function about the current mark */
  244. #ifdef ANSI_C
  245. int mem_stat_show_mark(void)
  246. #else
  247. int mem_stat_show_mark()
  248. #endif
  249. {
  250. return mem_stat_mark_curr;
  251. }
  252. /* Varying number of arguments */
  253. #ifdef ANSI_C
  254. /* To allocate memory to many arguments.
  255. The function should be called:
  256. mem_stat_vars(list,type,&v1,&v2,&v3,...,VNULL);
  257. where
  258. int list,type;
  259. void **v1, **v2, **v3,...;
  260. The last argument should be VNULL !
  261. type is the type of variables v1,v2,v3,...
  262. (of course they must be of the same type)
  263. */
  264. int mem_stat_reg_vars(int list,int type,...)
  265. {
  266. va_list ap;
  267. int i=0;
  268. void **par;
  269. va_start(ap, type);
  270. while ((par = va_arg(ap,void **))) { /* NULL ends the list*/
  271. mem_stat_reg_list(par,type,list);
  272. i++;
  273. }
  274. va_end(ap);
  275. return i;
  276. }
  277. #elif VARARGS
  278. /* old varargs is used */
  279. /* To allocate memory to many arguments.
  280. The function should be called:
  281. mem_stat_vars(list,type,&v1,&v2,&v3,...,VNULL);
  282. where
  283. int list,type;
  284. void **v1, **v2, **v3,...;
  285. The last argument should be VNULL !
  286. type is the type of variables v1,v2,v3,...
  287. (of course they must be of the same type)
  288. */
  289. int mem_stat_reg_vars(va_alist) va_dcl
  290. {
  291. va_list ap;
  292. int type,list,i=0;
  293. void **par;
  294. va_start(ap);
  295. list = va_arg(ap,int);
  296. type = va_arg(ap,int);
  297. while ((par = va_arg(ap,void **))) { /* NULL ends the list*/
  298. mem_stat_reg_list(par,type,list);
  299. i++;
  300. }
  301. va_end(ap);
  302. return i;
  303. }
  304. #endif