PageRenderTime 40ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/src/tools/mmstat/unix/code/mm_orc.c

https://github.com/xrl/opensplice
C | 429 lines | 386 code | 31 blank | 12 comment | 51 complexity | d4ab400900885cca7ed24d2cdd424c02 MD5 | raw file
  1. /*
  2. * OpenSplice DDS
  3. *
  4. * This software and documentation are Copyright 2006 to 2011 PrismTech
  5. * Limited and its licensees. All rights reserved. See file:
  6. *
  7. * $OSPL_HOME/LICENSE
  8. *
  9. * for full copyright notice and license terms.
  10. *
  11. */
  12. #include "u_user.h"
  13. #include "c_base.h"
  14. #include "c__base.h"
  15. #include "c__extent.h"
  16. #include "c_avltree.h"
  17. #include "ut_collection.h"
  18. #include "os_stdlib.h"
  19. #include "c_module.h"
  20. #include "mm_orc.h"
  21. #include <sys/types.h>
  22. #include <regex.h>
  23. #include <errno.h>
  24. #define MM_HEADER_SIZE 16 /* Assumed header size */
  25. /* c_base definitions */
  26. #define CONFIDENCE (0x504F5448)
  27. #define c_oid(o) ((c_object)(C_ADDRESS(o) + HEADERSIZE))
  28. #define c_header(o) ((c_header)(C_ADDRESS(o) - HEADERSIZE))
  29. #define MIN_DB_SIZE (150000)
  30. #define MAXREFCOUNT (50000)
  31. #define MAXALIGNMENT (C_ALIGNMENT(c_value))
  32. #define ALIGNSIZE(size) ((((size-1)/MAXALIGNMENT)+1)*MAXALIGNMENT)
  33. #define MEMSIZE(size) ((size)+HEADERSIZE)
  34. #define ResolveType(s,t) c_type(c_metaResolve(c_metaObject(s),#t))
  35. C_CLASS(c_baseBinding);
  36. #ifndef _DA_
  37. #ifndef __DA_
  38. C_CLASS(c_header);
  39. C_STRUCT(c_header) {
  40. #ifndef NDEBUG
  41. c_ulong confidence;
  42. #ifdef OBJECT_WALK
  43. c_object nextObject;
  44. c_object prevObject;
  45. #endif
  46. #endif
  47. c_ulong refCount;
  48. c_type type;
  49. };
  50. #endif
  51. #endif
  52. C_STRUCT(monitor_orc) {
  53. c_ulong extendCountLimit;
  54. char *filterExpression;
  55. regex_t expression;
  56. ut_collection refTree;
  57. int totalObjectCount;
  58. int totalSizeCount;
  59. c_bool delta;
  60. };
  61. static const c_long HEADERSIZE = ALIGNSIZE(C_SIZEOF(c_header));
  62. C_CLASS(refLeaf);
  63. C_STRUCT(refLeaf) {
  64. c_type tr;
  65. unsigned int rc;
  66. unsigned int prc;
  67. };
  68. static char *baseKind [] = {
  69. "M_UNDEFINED",
  70. "M_ATTRIBUTE",
  71. "M_CLASS",
  72. "M_COLLECTION",
  73. "M_CONSTANT",
  74. "M_CONSTOPERAND",
  75. "M_ENUMERATION",
  76. "M_EXCEPTION",
  77. "M_EXPRESSION",
  78. "M_INTERFACE",
  79. "M_LITERAL",
  80. "M_MEMBER",
  81. "M_MODULE",
  82. "M_OPERATION",
  83. "M_PARAMETER",
  84. "M_PRIMITIVE",
  85. "M_RELATION",
  86. "M_BASE",
  87. "M_STRUCTURE",
  88. "M_TYPEDEF",
  89. "M_UNION",
  90. "M_UNIONCASE",
  91. "M_COUNT"
  92. };
  93. static char *collectionKind [] = {
  94. "C_UNDEFINED",
  95. "C_LIST",
  96. "C_ARRAY",
  97. "C_BAG",
  98. "C_SET",
  99. "C_MAP",
  100. "C_DICTIONARY",
  101. "C_SEQUENCE",
  102. "C_STRING",
  103. "C_WSTRING",
  104. "C_QUERY",
  105. "C_SCOPE",
  106. "C_COUNT"
  107. };
  108. static c_type nullType = (c_type)0xffffffff;
  109. static void
  110. freeNode (
  111. c_object o,
  112. c_voidp arg
  113. )
  114. {
  115. free (o);
  116. }
  117. static c_equality
  118. compareLeafs (
  119. c_object o1,
  120. c_object o2,
  121. c_voidp args
  122. )
  123. {
  124. if (o1 < o2) {
  125. return C_LT;
  126. } else if (o1 > o2) {
  127. return C_GT;
  128. }
  129. return C_EQ;
  130. }
  131. monitor_orc
  132. monitor_orcNew (
  133. c_long extendCountLimit,
  134. const char*filterExpression,
  135. c_bool delta
  136. )
  137. {
  138. char expressionError [1024];
  139. monitor_orc o = malloc (C_SIZEOF(monitor_orc));
  140. if (o) {
  141. o->extendCountLimit = extendCountLimit;
  142. }
  143. if (filterExpression) {
  144. o->filterExpression = os_strdup(filterExpression);
  145. } else {
  146. o->filterExpression = NULL;
  147. }
  148. if (o->filterExpression) {
  149. if (regcomp (&o->expression, o->filterExpression, REG_EXTENDED) != 0) {
  150. regerror (errno, &o->expression, expressionError, sizeof(expressionError));
  151. printf ("Filter expression error: %s\r\n", expressionError);
  152. regfree (&o->expression);
  153. free (o->filterExpression);
  154. o->filterExpression = NULL;
  155. }
  156. }
  157. o->refTree = ut_tableNew (compareLeafs, NULL);
  158. o->totalSizeCount = 0;
  159. o->totalObjectCount = 0;
  160. o->delta = delta;
  161. return o;
  162. }
  163. static void
  164. monitor_object (
  165. c_object o,
  166. monitor_orc trace
  167. )
  168. {
  169. refLeaf ord;
  170. c_type tr = c_header(o)->type;
  171. if (tr == NULL) {
  172. tr = nullType;
  173. }
  174. ord = (refLeaf)ut_get (trace->refTree, tr);
  175. if (ord) {
  176. ord->rc++;
  177. } else {
  178. ord = malloc (C_SIZEOF(refLeaf));
  179. ord->tr = tr;
  180. ord->rc = 1;
  181. ord->prc = 0;
  182. ut_tableInsert(ut_table(trace->refTree), tr, ord);
  183. }
  184. }
  185. void
  186. monitor_orcFree (
  187. monitor_orc o
  188. )
  189. {
  190. if (o->filterExpression) {
  191. free (o->filterExpression);
  192. regfree (&o->expression);
  193. }
  194. ut_collectionFree (o->refTree, freeNode, NULL);
  195. free (o);
  196. }
  197. static void
  198. printScope (
  199. c_metaObject scope
  200. )
  201. {
  202. if (scope == NULL) {
  203. return;
  204. }
  205. if (scope->definedIn) {
  206. printScope (scope->definedIn);
  207. printf ("::%s", scope->name);
  208. } else {
  209. if (scope->name) {
  210. printf ("::%s", scope->name);
  211. }
  212. }
  213. }
  214. static c_bool
  215. display_orc (
  216. c_object o,
  217. c_voidp args
  218. )
  219. {
  220. refLeaf ord = (refLeaf)o;
  221. monitor_orc trace = (monitor_orc)args;
  222. regmatch_t match[1];
  223. if (ord->tr == nullType) {
  224. if (trace->delta) {
  225. if (abs(ord->rc - ord->prc) >= trace->extendCountLimit) {
  226. printf ("%6d <undefined>\r\n", (ord->rc - ord->prc));
  227. }
  228. } else {
  229. if (ord->rc >= trace->extendCountLimit) {
  230. printf ("%6d <undefined>\r\n", ord->rc);
  231. }
  232. }
  233. } else {
  234. switch (c_baseObject(ord->tr)->kind) {
  235. case M_COLLECTION:
  236. switch (c_collectionType(ord->tr)->kind) {
  237. case C_UNDEFINED:
  238. case C_LIST:
  239. case C_ARRAY:
  240. case C_BAG:
  241. case C_SET:
  242. case C_MAP:
  243. case C_DICTIONARY:
  244. case C_SEQUENCE:
  245. case C_STRING:
  246. case C_WSTRING:
  247. case C_QUERY:
  248. case C_SCOPE:
  249. case C_COUNT:
  250. if (trace->delta) {
  251. if (abs(ord->rc - ord->prc) >= trace->extendCountLimit) {
  252. if (trace->filterExpression) {
  253. if (regexec (&trace->expression, c_metaObject(ord->tr)->name, 1, match, 0) == REG_NOMATCH) {
  254. break;
  255. }
  256. }
  257. printf ("%6d (%6d) %6d %10d %-15s %-15s ",
  258. ord->rc - ord->prc,
  259. ord->rc,
  260. (int)c_type(ord->tr)->size,
  261. (int)(c_type(ord->tr)->size * (ord->rc - ord->prc)),
  262. baseKind[c_baseObject(ord->tr)->kind],
  263. collectionKind[c_collectionType(ord->tr)->kind]);
  264. printScope (c_metaObject(ord->tr)->definedIn);
  265. printf ("::%s\r\n", c_metaObject(ord->tr)->name);
  266. trace->totalSizeCount += c_type(ord->tr)->size * (ord->rc - ord->prc);
  267. trace->totalObjectCount += ord->rc - ord->prc;
  268. }
  269. } else {
  270. if (ord->rc >= trace->extendCountLimit) {
  271. if (trace->filterExpression) {
  272. if (regexec (&trace->expression, c_metaObject(ord->tr)->name, 1, match, 0) == REG_NOMATCH) {
  273. break;
  274. }
  275. }
  276. printf ("%6d %6d %10d %-15s %-15s ",
  277. ord->rc,
  278. (int)c_type(ord->tr)->size,
  279. (int)(c_type(ord->tr)->size * ord->rc),
  280. baseKind[c_baseObject(ord->tr)->kind],
  281. collectionKind[c_collectionType(ord->tr)->kind]);
  282. printScope (c_metaObject(ord->tr)->definedIn);
  283. printf ("::%s\r\n", c_metaObject(ord->tr)->name);
  284. trace->totalSizeCount += c_type(ord->tr)->size * ord->rc;
  285. trace->totalObjectCount += ord->rc;
  286. }
  287. }
  288. break;
  289. }
  290. break;
  291. case M_PRIMITIVE:
  292. case M_TYPEDEF:
  293. case M_ENUMERATION:
  294. case M_UNION:
  295. case M_STRUCTURE:
  296. case M_INTERFACE:
  297. case M_CLASS:
  298. case M_EXCEPTION:
  299. case M_EXTENT:
  300. case M_EXTENTSYNC:
  301. if (trace->delta) {
  302. if (abs(ord->rc - ord->prc) >= trace->extendCountLimit) {
  303. if (trace->filterExpression) {
  304. if (regexec (&trace->expression, c_metaObject(ord->tr)->name, 1, match, 0) == REG_NOMATCH) {
  305. break;
  306. }
  307. }
  308. printf ("%6d (%6d) %6d %10d %-15s ",
  309. ord->rc - ord->prc,
  310. ord->rc,
  311. (int)c_type(ord->tr)->size,
  312. (int)(c_type(ord->tr)->size * (ord->rc - ord->prc)),
  313. baseKind[c_baseObject(ord->tr)->kind]);
  314. printf (" ");
  315. printScope (c_metaObject(ord->tr)->definedIn);
  316. printf ("::%s\r\n", c_metaObject(ord->tr)->name);
  317. trace->totalSizeCount += c_type(ord->tr)->size * (ord->rc - ord->prc);
  318. trace->totalObjectCount += ord->rc - ord->prc;
  319. }
  320. } else {
  321. if (ord->rc >= trace->extendCountLimit) {
  322. if (trace->filterExpression) {
  323. if (regexec (&trace->expression, c_metaObject(ord->tr)->name, 1, match, 0) == REG_NOMATCH) {
  324. break;
  325. }
  326. }
  327. printf ("%6d %6d %10d %-15s ",
  328. ord->rc,
  329. (int)c_type(ord->tr)->size,
  330. (int)(c_type(ord->tr)->size * ord->rc),
  331. baseKind[c_baseObject(ord->tr)->kind]);
  332. printf (" ");
  333. printScope (c_metaObject(ord->tr)->definedIn);
  334. printf ("::%s\r\n", c_metaObject(ord->tr)->name);
  335. trace->totalSizeCount += c_type(ord->tr)->size * ord->rc;
  336. trace->totalObjectCount += ord->rc;
  337. }
  338. }
  339. break;
  340. case M_UNDEFINED:
  341. case M_ATTRIBUTE:
  342. case M_CONSTANT:
  343. case M_CONSTOPERAND:
  344. case M_EXPRESSION:
  345. case M_LITERAL:
  346. case M_MEMBER:
  347. case M_OPERATION:
  348. case M_PARAMETER:
  349. case M_RELATION:
  350. case M_BASE:
  351. case M_UNIONCASE:
  352. case M_COUNT:
  353. case M_MODULE:
  354. break;
  355. }
  356. }
  357. ord->prc = ord->rc;
  358. ord->rc = 0;
  359. return TRUE;
  360. }
  361. void
  362. monitor_orcAction (
  363. v_entity entity,
  364. c_voidp args
  365. )
  366. {
  367. #ifdef OBJECT_WALK
  368. c_base base;
  369. c_object or;
  370. monitor_orc trace = monitor_orc(args);
  371. time_t t;
  372. int count = 0;
  373. int totalSize;
  374. time (&t);
  375. base = c_getBase(entity);
  376. printf ("\r\n################# Start tracing ################## %s\r\n", ctime(&t));
  377. printf ("Limit : %d\r\n", trace->extendCountLimit);
  378. if (trace->filterExpression) {
  379. printf ("Filter expression : %s\r\n", trace->filterExpression);
  380. }
  381. printf ("\r\n");
  382. for (or = base->firstObject; or != base->lastObject; ) {
  383. or = c_header(or)->nextObject;
  384. monitor_object (or, trace);
  385. count++;
  386. };
  387. ut_walk (trace->refTree, display_orc, trace);
  388. printf ("\r\n");
  389. printf (" %d for %d object headers (%d) and MM headers (%d)\r\n",
  390. trace->totalObjectCount * (C_SIZEOF(c_header) + MM_HEADER_SIZE),
  391. trace->totalObjectCount,
  392. C_SIZEOF(c_header), MM_HEADER_SIZE);
  393. totalSize = trace->totalSizeCount + trace->totalObjectCount * (C_SIZEOF(c_header) + MM_HEADER_SIZE);
  394. printf ("Total : %d (%.2f KB)\r\n", totalSize, (double)totalSize/1024.0);
  395. trace->totalSizeCount = 0;
  396. trace->totalObjectCount = 0;
  397. #endif
  398. }