meminfo.c 10 KB

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