HPCToolkit
agent-cilk.c
Go to the documentation of this file.
1 // -*-Mode: C++;-*- // technically C99
2 
3 // * BeginRiceCopyright *****************************************************
4 //
5 // $HeadURL$
6 // $Id$
7 //
8 // --------------------------------------------------------------------------
9 // Part of HPCToolkit (hpctoolkit.org)
10 //
11 // Information about sources of support for research and development of
12 // HPCToolkit is at 'hpctoolkit.org' and in 'README.Acknowledgments'.
13 // --------------------------------------------------------------------------
14 //
15 // Copyright ((c)) 2002-2019, Rice University
16 // All rights reserved.
17 //
18 // Redistribution and use in source and binary forms, with or without
19 // modification, are permitted provided that the following conditions are
20 // met:
21 //
22 // * Redistributions of source code must retain the above copyright
23 // notice, this list of conditions and the following disclaimer.
24 //
25 // * Redistributions in binary form must reproduce the above copyright
26 // notice, this list of conditions and the following disclaimer in the
27 // documentation and/or other materials provided with the distribution.
28 //
29 // * Neither the name of Rice University (RICE) nor the names of its
30 // contributors may be used to endorse or promote products derived from
31 // this software without specific prior written permission.
32 //
33 // This software is provided by RICE and contributors "as is" and any
34 // express or implied warranties, including, but not limited to, the
35 // implied warranties of merchantability and fitness for a particular
36 // purpose are disclaimed. In no event shall RICE or contributors be
37 // liable for any direct, indirect, incidental, special, exemplary, or
38 // consequential damages (including, but not limited to, procurement of
39 // substitute goods or services; loss of use, data, or profits; or
40 // business interruption) however caused and on any theory of liability,
41 // whether in contract, strict liability, or tort (including negligence
42 // or otherwise) arising in any way out of the use of this software, even
43 // if advised of the possibility of such damage.
44 //
45 // ******************************************************* EndRiceCopyright *
46 
47 //***************************************************************************
48 //
49 // File:
50 // $HeadURL$
51 //
52 // Purpose:
53 // LUSH: Logical Unwind Support for HPCToolkit
54 //
55 // Description:
56 // [The set of functions, macros, etc. defined in the file]
57 //
58 // Author:
59 // Nathan Tallent, Rice University.
60 //
61 //***************************************************************************
62 
63 //************************* System Include Files ****************************
64 
65 #include <stdlib.h>
66 #include <stdbool.h>
67 
68 #include <pthread.h>
69 
70 #include <string.h>
71 
72 #include <limits.h> // PATH_MAX
73 #include <errno.h>
74 
75 //*************************** User Include Files ****************************
76 
77 #include "agent-cilk.h"
78 
79 #include <messages/messages.h>
80 
81 //*************************** Forward Declarations **************************
82 
83 #define LUSHCB_DECL(FN) \
84  LUSH ## FN ## _fn_t FN
85 
86 LUSHCB_DECL(CB_malloc);
87 LUSHCB_DECL(CB_free);
88 LUSHCB_DECL(CB_step);
89 LUSHCB_DECL(CB_loadmap_find);
90 // lush_cursor stuff
91 
92 #undef LUSHCB_DECL
93 
95 
96 //*************************** Forward Declarations **************************
97 
98 // FIXME: hackish implementation
99 static const char* libcilk_str = "libcilk";
100 static const char* lib_str = "lib";
101 static const char* ld_str = "ld-linux";
102 
103 //*************************** Forward Declarations **************************
104 
105 static int
106 init_lcursor(lush_cursor_t* cursor);
107 
108 static unw_seg_t
110 
111 static unw_seg_t
112 peek_segment(lush_cursor_t* cursor);
113 
114 static bool
115 is_libcilk(void* addr, char* lm_buffer /*helper storage*/);
116 
117 static bool
118 is_cilkprogram(void* addr, char* lm_buffer /*helper storage*/);
119 
120 
121 // **************************************************************************
122 // Initialization/Finalization
123 // **************************************************************************
124 
125 extern int
126 LUSHI_init(int argc, char** argv,
127  lush_agentid_t aid,
128  LUSHCB_malloc_fn_t malloc_fn,
129  LUSHCB_free_fn_t free_fn,
130  LUSHCB_step_fn_t step_fn,
131  LUSHCB_loadmap_find_fn_t loadmap_fn)
132 {
133  MY_lush_aid = aid;
134 
135  CB_malloc = malloc_fn;
136  CB_free = free_fn;
137  CB_step = step_fn;
138  CB_loadmap_find = loadmap_fn;
139 
140  return 0;
141 }
142 
143 
144 extern int
146 {
147  return 0;
148 }
149 
150 
151 extern char*
152 LUSHI_strerror(int code)
153 {
154  return ""; // STUB
155 }
156 
157 
158 // **************************************************************************
159 // Maintaining Responsibility for Code/Frame-space
160 // **************************************************************************
161 
162 extern int
164 {
165  return 0; // FIXME: coordinate with dylib stuff
166 }
167 
168 
169 extern bool
171 {
172  char buffer[PATH_MAX];
173  return (is_libcilk(addr, buffer) || is_cilkprogram(addr, buffer));
174 }
175 
176 
177 bool
178 is_libcilk(void* addr, char* lm_name /*helper storage*/)
179 {
180  void *lm_beg, *lm_end;
181  int ret = CB_loadmap_find(addr, lm_name, &lm_beg, &lm_end);
182  if (ret && strstr(lm_name, libcilk_str)) {
183  return true;
184  }
185  return false;
186 }
187 
188 
189 bool
190 is_cilkprogram(void* addr, char* lm_name /*helper storage*/)
191 {
192  void *lm_beg, *lm_end;
193  int ret = CB_loadmap_find(addr, lm_name, &lm_beg, &lm_end);
194  if (ret && !(strstr(lm_name, lib_str) || strstr(lm_name, ld_str))) {
195  return true;
196  }
197  return false;
198 }
199 
200 
201 // **************************************************************************
202 //
203 // **************************************************************************
204 
205 extern lush_step_t
207 {
208  // -------------------------------------------------------
209  // Initialize cursor
210  // -------------------------------------------------------
211  int ret = init_lcursor(cursor);
212  if (ret != 0) {
213  return LUSH_STEP_ERROR;
214  }
216 
217  // -------------------------------------------------------
218  // Compute p-note's current stack segment ('cur_seg')
219  // -------------------------------------------------------
220  unw_seg_t cur_seg = classify_by_unw_segment(csr);
221 
222  // -------------------------------------------------------
223  // Given p-note derive l-note:
224  // -------------------------------------------------------
225 
226  // FIXME: consider effects of multiple agents
227  //lush_agentid_t last_aid = lush_cursor_get_aid(cursor);
228 
229  if (cur_seg == UnwSeg_CilkRT) {
230  // INVARIANT: unw_ty_is_worker() == true
232  }
233  else if (cur_seg == UnwSeg_User) {
234  // INVARIANT: unw_ty_is_worker() == true
235  CilkWorkerState* ws = csr->u.cilk_worker_state;
236  if (ws && ws->self == 0 && peek_segment(cursor) == UnwSeg_CilkSched) {
237  // local stack: import_cilk_main -> cilk_main (skip the former)
238  lush_cursor_set_assoc(cursor, LUSH_ASSOC_0_to_0); // skip
239  }
240  else {
242  }
243  }
244  else if (cur_seg == UnwSeg_CilkSched) {
245  switch (csr->u.ty) {
246  case UnwTy_Master:
248  break;
249  case UnwTy_WorkerLcl:
250  if (csr->u.prev_seg == UnwSeg_User
251  && !csr_is_flag(csr, UnwFlg_HaveLCtxt)) {
254  }
255  else if (csr_is_flag(csr, UnwFlg_HaveLCtxt)) {
256  lush_cursor_set_assoc(cursor, LUSH_ASSOC_0_to_0); // skip
257  }
258  else {
260  }
261  break;
262  case UnwTy_Worker:
263  if (csr->u.prev_seg == UnwSeg_User
264  && !csr_is_flag(csr, UnwFlg_HaveLCtxt)) {
267  }
268  else if (csr_is_flag(csr, UnwFlg_HaveLCtxt)) {
269  lush_cursor_set_assoc(cursor, LUSH_ASSOC_0_to_0); // skip
270  }
271  else {
273  }
274  break;
275  default: EEMSG("FIXME: default case (assert)\n");
276  }
277  }
278  else {
279  EEMSG("FIXME: Unknown segment! (assert)\n");
280  }
281 
282 
283  // record for next bi-chord
284  csr->u.prev_seg = cur_seg;
285 
286  return LUSH_STEP_CONT;
287 }
288 
289 
290 extern lush_step_t
292 {
293  // NOTE: Since all associations are 1-to-a, it is always valid to step.
294 
296 
297  int t = CB_step(lush_cursor_get_pcursor(cursor));
298  if (t > 0) {
299  ty = LUSH_STEP_END_CHORD;
300  }
301  else if (t == 0) {
302  ty = LUSH_STEP_END_PROJ;
303  }
304  else /* (t < 0) */ {
305  ty = LUSH_STEP_ERROR;
306  }
307 
308  return ty;
309 }
310 
311 
312 #define SET_LIP_AND_TY(cl, lip, ty) \
313  if (!cl) { \
314  cilk_ip_set(lip, ip_normalized_NULL_lval); \
315  ty = LUSH_STEP_END_CHORD; \
316  } \
317  else { \
318  /* NOTE: interior lips should act like a return address; */ \
319  /* therefore, we add 1 */ \
320  ip_normalized_t ip = \
321  hpcrun_normalize_ip(CILKFRM_PROC(cl->frame) + 1, NULL); \
322  cilk_ip_set(lip, ip); \
323  ty = LUSH_STEP_CONT; \
324  }
325 
326 extern lush_step_t
328 {
330 
331  lush_assoc_t as = lush_cursor_get_assoc(cursor);
333  cilk_ip_t* lip = (cilk_ip_t*)lush_cursor_get_lip(cursor);
334 
335  if (lush_assoc_is_a_to_0(as)) {
336  ty = LUSH_STEP_END_CHORD;
337  }
338  else if (as == LUSH_ASSOC_1_to_1) {
339  if (csr_is_flag(csr, UnwFlg_BegLNote)) {
340  ty = LUSH_STEP_END_CHORD;
341  }
342  else {
343  cilk_ip_set(lip, csr->u.ref_ip_norm);
344  ty = LUSH_STEP_CONT;
346  }
347  }
348  else if (as == LUSH_ASSOC_1_to_M) {
349  // INVARIANT: csr->u.cilk_closure is non-NULL
350  Closure* cl = csr->u.cilk_closure;
351  if (csr_is_flag(csr, UnwFlg_BegLNote)) { // after innermost closure
352  // advance to next closure
353  cl = csr->u.cilk_closure = cl->parent;
354  SET_LIP_AND_TY(cl, lip, ty);
355  }
356  else {
357  // skip innermost closure; it is identical to the outermost stack frame
358  cl = csr->u.cilk_closure = cl->parent;
359  SET_LIP_AND_TY(cl, lip, ty);
361  }
362  }
363  else {
364  ty = LUSH_STEP_ERROR;
365  }
366 
367  return ty;
368 }
369 
370 
371 extern int
373 {
374  return 0; // STUB
375 }
376 
377 
378 // **************************************************************************
379 //
380 // **************************************************************************
381 
382 static int
384 {
385  lush_lip_t* lip = lush_cursor_get_lip(cursor);
387  lush_agentid_t aid_prev = lush_cursor_get_aid_prev(cursor);
388 
389  // -------------------------------------------------------
390  // inter-bichord data
391  // -------------------------------------------------------
392  if (aid_prev == lush_agentid_NULL) {
393  CilkWorkerState* ws =
394  (CilkWorkerState*)pthread_getspecific(CILK_WorkerState_key);
395  Closure* cactus_stack = (ws) ? CILKWS_CL_DEQ_BOT(ws) : NULL;
396 
397  // unw_ty_t
398  if (!ws) {
399  csr->u.ty = UnwTy_Master;
400  }
401  else {
402  csr->u.ty = (cactus_stack) ? UnwTy_Worker : UnwTy_WorkerLcl;
403 
404  if (CILK_WS_has_stolen(ws) && !cactus_stack) {
405  // Sometimes we are hammered in the middle of a Cilk operation
406  // where the cactus stack pointer becomes NULL, even though
407  // logical context 'should' exist (e.g., Cilk_sync before a
408  // return). The result is that we cannot obtain the logical
409  // context and therefore cannot locate the unwind correctly
410  // within the CCT.
411  //
412  // To avoid such bad unwinds, we use the simple heuristic of
413  // requiring a cactus stack pointer if the worker has become a
414  // thief. It is not a perfect solution since a worker may have
415  // stolen the main routine; however, this is an exceptional
416  // case.
417  //
418  // FIXME: the best solution is to find the smallest window
419  // within the scheduler code and set a flag. But I found that
420  // this is easier said than done.
421  return 1;
422  }
423  }
424 
425  csr->u.prev_seg = UnwSeg_NULL;
426 
427  csr->u.flg = UnwFlg_NULL;
428 
429  csr->u.cilk_worker_state = ws;
430  csr->u.cilk_closure = cactus_stack;
431  }
432  else if (aid_prev != MY_lush_aid) {
433  EEMSG("FIXME: HOW TO HANDLE MULTIPLE AGENTS?\n");
434  }
435 
436  // -------------------------------------------------------
437  // intra-bichord data
438  // -------------------------------------------------------
439  memset(lip, 0, sizeof(*lip));
440 
441  csr->u.ref_ip = (void*)lush_cursor_get_ip_unnorm(cursor);
442  csr->u.ref_ip_norm = lush_cursor_get_ip_norm(cursor);
443 
445 
446  return 0;
447 }
448 
449 
450 // Classify the cursor by the unw segment (physical stack)
451 // NOTE: may set a flag within 'csr'
452 static unw_seg_t
454 {
455  unw_seg_t cur_seg = UnwSeg_NULL;
456 
457  char buffer[PATH_MAX];
458  bool is_cilkrt = is_libcilk(csr->u.ref_ip, buffer);
459  bool is_user = is_cilkprogram(csr->u.ref_ip, buffer);
460 
461  if (unw_ty_is_worker(csr->u.ty)) {
462  // -------------------------------------------------------
463  // 1. is_cilkrt & (deq_diff <= 1) => UnwSeg_CilkSched
464  // 2. is_cilkrt & !(deq_diff <= 1) => UnwSeg_CilkRT
465  // 3. is_user => UnwSeg_User
466  // -------------------------------------------------------
467  CilkWorkerState* ws = csr->u.cilk_worker_state;
468  long deq_diff = CILKWS_FRAME_DEQ_TAIL(ws) - CILKWS_FRAME_DEQ_HEAD(ws);
469 
470  if (is_user) {
471  cur_seg = UnwSeg_User;
473  }
474  else if (is_cilkrt) {
475  cur_seg = (deq_diff <= 1) ? UnwSeg_CilkSched : UnwSeg_CilkRT;
476 
477  // FIXME: sometimes the above test is not correct... OVERRIDE
478  if (cur_seg == UnwSeg_CilkRT && csr_is_flag(csr, UnwFlg_SeenUser)) {
479  cur_seg = UnwSeg_CilkSched;
480  }
481  }
482  else {
483  EEMSG("FIXME: (assert): neither cilkrt nor user\n");
484  }
485  }
486  else if (unw_ty_is_master(csr->u.ty)) {
487  cur_seg = UnwSeg_CilkSched;
488  if ( !(is_user || is_cilkrt) ) {
489  // is_user may be true when executing main
490  EEMSG("FIXME: Unknown segment for master (assert)\n");
491  }
492  }
493  else {
494  EEMSG("FIXME: Unknown thread type! (assert)\n");
495  }
496 
497  return cur_seg;
498 }
499 
500 
501 static unw_seg_t
503 {
504  lush_cursor_t tmp_cursor = *cursor;
505 
506  unw_seg_t cur_seg = UnwSeg_NULL;
507 
508  lush_step_t ty = LUSHI_step_pnote(&tmp_cursor);
509  if ( !(ty == LUSH_STEP_END_PROJ || ty == LUSH_STEP_ERROR) ) {
511  csr->u.ref_ip = (void*)lush_cursor_get_ip_unnorm(&tmp_cursor);
512  csr->u.ref_ip_norm = lush_cursor_get_ip_norm(&tmp_cursor);
513  cur_seg = classify_by_unw_segment(csr);
514  }
515 
516  return cur_seg;
517 }
518 
519 
520 // **************************************************************************
521 //
522 // **************************************************************************
523 
524 extern int
526 {
527  return 0; // STUB
528 }
529 
530 
531 extern int
533 {
534  return 0; // STUB
535 }
536 
537 
538 extern int
540 {
541  return 0; // STUB
542 }
543 
544 
545 extern int
547 {
548  return 0; // STUB
549 }
550 
551 
552 // **************************************************************************
553 // Metrics
554 // **************************************************************************
555 
556 extern bool
557 LUSHI_do_metric(uint64_t incrMetricIn,
558  bool* doMetric, bool* doMetricIdleness,
559  uint64_t* incrMetric, double* incrMetricIdleness)
560 {
561  // INVARIANT: at least one thread is working
562  // INVARIANT: ws is non-NULL
563 
564  CilkWorkerState* ws =
565  (CilkWorkerState*)pthread_getspecific(CILK_WorkerState_key);
566  bool isWorking = (ws && CILK_WS_is_working(ws));
567 
568  if (isWorking) {
569  double n = CILK_WS_num_workers(ws);
570  double n_working = (double)CILK_Threads_Working;
571  double n_not_working = n - n_working;
572 
573  // NOTE: if n_working == 0, then Cilk should be in the process of
574  // exiting. Protect against samples in this timing window.
575  double idleness = 0.0;
576  if (n_working > 0) {
577  idleness = ((double)incrMetricIn * n_not_working) / n_working;
578  }
579 
580  *doMetric = true;
581  *doMetricIdleness = true;
582  *incrMetric = incrMetricIn;
583  *incrMetricIdleness = idleness;
584  }
585  else {
586  *doMetric = false;
587  *doMetricIdleness = false;
588  //*incrMetric = 0;
589  //*incrMetricIdleness = 0.0;
590  }
591  return *doMetric;
592 }
593 
594 
595 // **************************************************************************
#define lush_agentid_NULL
Definition: lush-support.h:98
lush_step_t LUSHI_step_bichord(lush_cursor_t *cursor)
Definition: agent-cilk.c:206
char * LUSHI_strerror(int code)
Definition: agent-cilk.c:152
static lush_lip_t * lush_cursor_get_lip(lush_cursor_t *cursor)
static lush_agentid_t lush_cursor_get_aid_prev(lush_cursor_t *cursor)
static volatile CilkStackFrame ** CILKWS_FRAME_DEQ_TAIL(CilkWorkerState *x)
Definition: agent-cilk.h:259
int LUSHI_fini()
Definition: agent-cilk.c:145
lush_step_t LUSHI_step_lnote(lush_cursor_t *cursor)
Definition: agent-cilk.c:327
unw_ty_t ty
Definition: agent-cilk.h:201
int LUSHI_init(int argc, char **argv, lush_agentid_t aid, LUSHCB_malloc_fn_t malloc_fn, LUSHCB_free_fn_t free_fn, LUSHCB_step_fn_t step_fn, LUSHCB_loadmap_find_fn_t loadmap_fn)
Definition: agent-cilk.c:126
int LUSHI_reg_dlopen()
Definition: agent-cilk.c:163
bool LUSHI_do_metric(uint64_t incrMetricIn, bool *doMetric, bool *doMetricIdleness, uint64_t *incrMetric, double *incrMetricIdleness)
Definition: agent-cilk.c:557
bool LUSHI_ismycode(void *addr)
Definition: agent-cilk.c:170
unw_flg_t flg
Definition: agent-cilk.h:203
static bool unw_ty_is_worker(unw_ty_t ty)
Definition: agent-cilk.h:148
#define SET_LIP_AND_TY(cl, lip, ty)
Definition: agent-cilk.c:312
struct cilk_cursor::@13 u
static void cilk_ip_set(cilk_ip_t *x, ip_normalized_t ip)
Definition: agent-cilk.h:115
static int init_lcursor(lush_cursor_t *cursor)
Definition: agent-cilk.c:383
static void csr_unset_flag(cilk_cursor_t *csr, unw_flg_t flg)
Definition: agent-cilk.h:231
static unw_seg_t classify_by_unw_segment(cilk_cursor_t *csr)
Definition: agent-cilk.c:453
static void * lush_cursor_get_ip_unnorm(lush_cursor_t *cursor)
static const char * libcilk_str
Definition: agent-cilk.c:99
lush_step_t LUSHI_step_pnote(lush_cursor_t *cursor)
Definition: agent-cilk.c:291
static bool is_cilkprogram(void *addr, char *lm_buffer)
Definition: agent-cilk.c:190
static Closure * CILKWS_CL_DEQ_BOT(CilkWorkerState *x)
Definition: agent-cilk.h:247
static bool is_libcilk(void *addr, char *lm_buffer)
Definition: agent-cilk.c:178
static bool lush_assoc_is_a_to_0(lush_assoc_t as)
Definition: lush-support.h:191
enum unw_seg_e unw_seg_t
Definition: agent-cilk.h:158
int LUSHI_set_active_frame_marker()
Definition: agent-cilk.c:372
#define doMetric(metricIdExpr, metricIncr, type)
Definition: ga-overrides.c:296
ip_normalized_t ref_ip_norm
Definition: agent-cilk.h:212
static ip_normalized_t lush_cursor_get_ip_norm(lush_cursor_t *cursor)
int lush_agentid_t
Definition: lush-support.h:99
void * ref_ip
Definition: agent-cilk.h:211
static volatile CilkStackFrame ** CILKWS_FRAME_DEQ_HEAD(CilkWorkerState *x)
Definition: agent-cilk.h:253
static unw_seg_t peek_segment(lush_cursor_t *cursor)
Definition: agent-cilk.c:502
static void csr_set_flag(cilk_cursor_t *csr, unw_flg_t flg)
Definition: agent-cilk.h:225
int LUSHI_lip_eq(lush_lip_t *lip)
Definition: agent-cilk.c:532
CilkWorkerState * cilk_worker_state
Definition: agent-cilk.h:205
enum lush_step lush_step_t
static void lush_cursor_set_assoc(lush_cursor_t *cursor, lush_assoc_t as)
enum lush_assoc lush_assoc_t
Definition: lush-support.h:164
static lush_assoc_t lush_cursor_get_assoc(lush_cursor_t *cursor)
static const char * ld_str
Definition: agent-cilk.c:101
static lush_agentid_t MY_lush_aid
Definition: agent-cilk.c:94
static hpcrun_unw_cursor_t * lush_cursor_get_pcursor(lush_cursor_t *cursor)
int LUSHI_lip_write()
Definition: agent-cilk.c:546
#define EEMSG(...)
Definition: messages.h:90
#define NULL
Definition: ElfHelper.cpp:85
int LUSHI_lip_destroy(lush_lip_t *lip)
Definition: agent-cilk.c:525
static const char * lib_str
Definition: agent-cilk.c:100
cct_addr_t * addr
Definition: cct.c:130
Closure * cilk_closure
Definition: agent-cilk.h:206
<!-- ********************************************************************--> n<!-- HPCToolkit Experiment DTD --> n<!-- Version 2.1 --> n<!-- ********************************************************************--> n<!ELEMENT HPCToolkitExperiment(Header,(SecCallPathProfile|SecFlatProfile) *)> n<!ATTLIST HPCToolkitExperiment\n version CDATA #REQUIRED > n n<!-- ******************************************************************--> n n<!-- Info/NV:flexible name-value pairs:(n) ame;(t) ype;(v) alue --> n<!ELEMENT Info(NV *)> n<!ATTLIST Info\n n CDATA #IMPLIED > n<!ELEMENT NV EMPTY > n<!ATTLIST NV\n n CDATA #REQUIRED\n t CDATA #IMPLIED\n v CDATA #REQUIRED > n n<!-- ******************************************************************--> n<!-- Header --> n<!-- ******************************************************************--> n<!ELEMENT Header(Info *)> n<!ATTLIST Header\n n CDATA #REQUIRED > n n<!-- ******************************************************************--> n<!-- Section Header --> n<!-- ******************************************************************--> n<!ELEMENT SecHeader(MetricTable?, MetricDBTable?, TraceDBTable?, LoadModuleTable?, FileTable?, ProcedureTable?, Info *)> n n<!-- MetricTable:--> n<!ELEMENT MetricTable(Metric) * > n n<!-- Metric:(i) d;(n) ame --> n<!--(v) alue-type:transient type of values --> n<!--(t) ype:persistent type of metric --> n<!-- fmt:format;show;--> n<!ELEMENT Metric(MetricFormula *, Info?)> n<!ATTLIST Metric\n i CDATA #REQUIRED\n n CDATA #REQUIRED\n es CDATA #IMPLIED\n em CDATA #IMPLIED\n ep CDATA #IMPLIED\n v(raw|final|derived-incr|derived) \"raw\\ t (inclusive|exclusive|nil) \nil\\ partner CDATA #IMPLIED\ fmt CDATA #IMPLIED\ show (1|0) \1\\ show-percent (1|0) \1> n n<!-- MetricFormula represents derived metrics: (t)ype; (frm): formula --> n<!ELEMENT MetricFormula (Info?)> n<!ATTLIST MetricFormula\ t (combine|finalize) \finalize\\ i CDATA #IMPLIED\ frm CDATA #REQUIRED> n n<!-- Metric data, used in sections: (n)ame [from Metric]; (v)alue --> n<!ELEMENT M EMPTY> n<!ATTLIST M\ n CDATA #REQUIRED\ v CDATA #REQUIRED> n n<!-- MetricDBTable: --> n<!ELEMENT MetricDBTable (MetricDB)*> n n<!-- MetricDB: (i)d; (n)ame --> n<!-- (t)ype: persistent type of metric --> n<!-- db-glob: file glob describing files in metric db --> n<!-- db-id: id within metric db --> n<!-- db-num-metrics: number of metrics in db --> n<!-- db-header-sz: size (in bytes) of a db file header --> n<!ELEMENT MetricDB EMPTY> n<!ATTLIST MetricDB\ i CDATA #REQUIRED\ n CDATA #REQUIRED\ t (inclusive|exclusive|nil) \nil\\ partner CDATA #IMPLIED\ db-glob CDATA #IMPLIED\ db-id CDATA #IMPLIED\ db-num-metrics CDATA #IMPLIED\ db-header-sz CDATA #IMPLIED> n n<!-- TraceDBTable: --> n<!ELEMENT TraceDBTable (TraceDB)> n n<!-- TraceDB: (i)d --> n<!-- db-min-time: min beginning time stamp (global) --> n<!-- db-max-time: max ending time stamp (global) --> n<!ELEMENT TraceDB EMPTY> n<!ATTLIST TraceDB\ i CDATA #REQUIRED\ db-glob CDATA #IMPLIED\ db-min-time CDATA #IMPLIED\ db-max-time CDATA #IMPLIED\ db-header-sz CDATA #IMPLIED> n n<!-- LoadModuleTable assigns a short name to a load module --> n<!ELEMENT LoadModuleTable (LoadModule)*> n n<!ELEMENT LoadModule (Info?)> n<!ATTLIST LoadModule\ i CDATA #REQUIRED\ n CDATA #REQUIRED> n n<!-- FileTable assigns a short name to a file --> n<!ELEMENT FileTable (File)*> n n<!ELEMENT File (Info?)> n<!ATTLIST File\ i CDATA #REQUIRED\ n CDATA #REQUIRED> n n<!-- ProcedureTable assigns a short name to a procedure --> n<!ELEMENT ProcedureTable (Procedure)*> n n<!-- Info/NV: flexible name-value pairs: (n)ame; (t)ype; (v)alue --> n<!-- f: family of the procedure (fake, root, ...)--> n<!ELEMENT Procedure (Info?)> n<!ATTLIST Procedure\ i CDATA #REQUIRED\ n CDATA #REQUIRED\ f CDATA #IMPLIED> n n<!-- ****************************************************************** --> n<!-- Section: Call path profile --> n<!-- ****************************************************************** --> n<!ELEMENT SecCallPathProfile (SecHeader, SecCallPathProfileData)> n<!ATTLIST SecCallPathProfile\ i CDATA #REQUIRED\ n CDATA #REQUIRED> n n<!ELEMENT SecCallPathProfileData (PF|M)*> n<!-- Procedure frame --> n<!-- (i)d: unique identifier for cross referencing --> n<!-- (s)tatic scope id --> n<!-- (n)ame: a string or an id in ProcedureTable --> n<!-- (lm) load module: a string or an id in LoadModuleTable --> n<!-- (f)ile name: a string or an id in LoadModuleTable --> n<!-- (l)ine range: \beg-end\ (inclusive range) --> n<!-- (a)lien: whether frame is alien to enclosing P --> n<!-- (str)uct: hpcstruct node id --> n<!-- (t)ype: hpcrun node type: memory access, variable declaration, ... --> n<!-- (v)ma-range-set: \{[beg-end), [beg-end)...}\ --> n<!ELEMENT PF (PF|Pr|L|C|S|M)*> n<!ATTLIST PF\ i CDATA #IMPLIED\ s CDATA #IMPLIED\ n CDATA #REQUIRED\ lm CDATA #IMPLIED\ f CDATA #IMPLIED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Procedure (static): GOAL: replace with 'P' --> n<!ELEMENT Pr (Pr|L|C|S|M)*> n<!ATTLIST Pr\ i CDATA #IMPLIED\ s CDATA #IMPLIED\ n CDATA #REQUIRED\ lm CDATA #IMPLIED\ f CDATA #IMPLIED\ l CDATA #IMPLIED\ a (1|0) \0\\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Callsite (a special StatementRange) --> n<!ELEMENT C (PF|M)*> n<!ATTLIST C\ i CDATA #IMPLIED\ s CDATA #IMPLIED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n n<!-- ****************************************************************** --> n<!-- Section: Flat profile --> n<!-- ****************************************************************** --> n<!ELEMENT SecFlatProfile (SecHeader, SecFlatProfileData)> n<!ATTLIST SecFlatProfile\ i CDATA #REQUIRED\ n CDATA #REQUIRED> n n<!ELEMENT SecFlatProfileData (LM|M)*> n<!-- Load module: (i)d; (n)ame; (v)ma-range-set --> n<!ELEMENT LM (F|P|M)*> n<!ATTLIST LM\ i CDATA #IMPLIED\ n CDATA #REQUIRED\ v CDATA #IMPLIED> n<!-- File --> n<!ELEMENT F (P|L|S|M)*> n<!ATTLIST F\ i CDATA #IMPLIED\ n CDATA #REQUIRED> n<!-- Procedure (Note 1) --> n<!ELEMENT P (P|A|L|S|C|M)*> n<!ATTLIST P\ i CDATA #IMPLIED\ n CDATA #REQUIRED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Alien (Note 1) --> n<!ELEMENT A (A|L|S|C|M)*> n<!ATTLIST A\ i CDATA #IMPLIED\ f CDATA #IMPLIED\ n CDATA #IMPLIED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Loop (Note 1,2) --> n<!ELEMENT L (A|Pr|L|S|C|M)*> n<!ATTLIST L\ i CDATA #IMPLIED\ s CDATA #IMPLIED\ l CDATA #IMPLIED\ f CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Statement (Note 2) --> n<!-- (it): trace record identifier --> n<!ELEMENT S (S|M)*> n<!ATTLIST S\ i CDATA #IMPLIED\ it CDATA #IMPLIED\ s CDATA #IMPLIED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Note 1: Contained Cs may not contain PFs --> n<!-- Note 2: The 's' attribute is not used for flat profiles --> n
unw_seg_t prev_seg
Definition: agent-cilk.h:202
int LUSHI_lip_read()
Definition: agent-cilk.c:539
#define LUSHCB_DECL(FN)
Definition: agent-cilk.c:83
static bool csr_is_flag(cilk_cursor_t *csr, unw_flg_t flg)
Definition: agent-cilk.h:219
static lush_lcursor_t * lush_cursor_get_lcursor(lush_cursor_t *cursor)
static bool unw_ty_is_master(unw_ty_t ty)
Definition: agent-cilk.h:142