cct_node_t*
hpcrun_cct_record_backtrace_w_metric(cct_bundle_t* cct, bool partial, bool thread_stop,
				     frame_t* bt_beg, frame_t* bt_last, bool tramp_found,
				     int metricId, uint64_t metricIncr)
{
  TMSG(FENCE, "Recording backtrace");
  TMSG(BT_INSERT, "Record backtrace w metric to id %d, incr = %d", metricId, metricIncr);
  thread_data_t* td = hpcrun_get_thread_data();
  cct_node_t* cct_cursor = cct->tree_root;
  TMSG(FENCE, "Initially picking tree root = %p", cct_cursor);
  if (tramp_found) {
    // start insertion below caller's frame, which is marked with the trampoline
    cct_cursor = hpcrun_cct_parent(td->tramp_cct_node);
    TMSG(FENCE, "Tramp found ==> cursor = %p", cct_cursor);
  }
  if (partial) {
    cct_cursor = cct->partial_unw_root;
    TMSG(FENCE, "Partial unwind ==> cursor = %p", cct_cursor);
  }
  if (thread_stop) {
    cct_cursor = cct->thread_root;
    TMSG(FENCE, "Thread stop ==> cursor = %p", cct_cursor);
  }

  TMSG(FENCE, "sanity check cursor = %p", cct_cursor);
  TMSG(FENCE, "further sanity check: bt_last frame = (%d, %p)", bt_last->ip_norm.lm_id, bt_last->ip_norm.lm_ip);
  return hpcrun_cct_insert_backtrace_w_metric(cct_cursor, metricId,
					      bt_last, bt_beg,
					      (cct_metric_data_t){.i = metricIncr});
Example #2
0
//
// Actually drop a sample, as opposed to recording a partial unwind
//
void
hpcrun_unw_drop(void)
{
  thread_data_t* td = hpcrun_get_thread_data();
  td->btbuf_cur = td->btbuf_beg; // flush any collected backtrace frames

  sigjmp_buf_t *it = &(td->bad_unwind);
  (*hpcrun_get_real_siglongjmp())(it->jb, 9);
}
Example #3
0
static void
METHOD_FN(shutdown)
{
  METHOD_CALL(self, stop); // make sure stop has been called
  TMSG(ITIMER_CTL, "shutdown %s", the_event_name);

  // delete the realtime timer to avoid a timer leak
  if (use_realtime || use_cputime) {
    thread_data_t *td = hpcrun_get_thread_data();
    hpcrun_delete_real_timer(td);
  }

  self->state = UNINIT;
}
Example #4
0
// Factor out the body of the start method so we can restart itimer
// without messages in the case that we are interrupting our own code.
// safe = 1 if not inside our code, so ok to print debug messages
//
static void
hpcrun_restart_timer(sample_source_t *self, int safe)
{
  int ret;

  // if thread data is unavailable, assume that all sample source ops
  // are suspended.
  if (! hpcrun_td_avail()) {
    if (safe) {
      TMSG(ITIMER_CTL, "Thread data unavailable ==> sampling suspended");
    }
    return;
  }
  thread_data_t *td = hpcrun_get_thread_data();

  if (safe) {
    TMSG(ITIMER_HANDLER, "starting %s: value = (%d,%d), interval = (%d,%d)",
	 the_event_name,
	 itval_start.it_value.tv_sec,
	 itval_start.it_value.tv_usec,
	 itval_start.it_interval.tv_sec,
	 itval_start.it_interval.tv_usec);
  }

  ret = hpcrun_start_timer(td);
  if (ret != 0) {
    if (safe) {
      TMSG(ITIMER_CTL, "setitimer failed to start!!");
      EMSG("setitimer failed (%d): %s", errno, strerror(errno));
    }
    hpcrun_ssfail_start("itimer");
  }

#ifdef USE_ELAPSED_TIME_FOR_WALLCLOCK
  ret = time_getTimeReal(&TD_GET(last_time_us));
  if (ret != 0) {
    if (safe) {
      EMSG("time_getTimeReal (clock_gettime) failed!");
    }
    monitor_real_abort();
  }
#endif

  TD_GET(ss_state)[self->sel_idx] = START;
}
Example #5
0
static void
METHOD_FN(stop)
{
  TMSG(ITIMER_CTL, "stop %s", the_event_name);

  // itimer is process-wide, so it's worth blocking the signal in the
  // current thread at stop time.
  if (use_itimer) {
    monitor_real_pthread_sigmask(SIG_BLOCK, &timer_mask, NULL);
  }

  thread_data_t *td = hpcrun_get_thread_data();
  int rc = hpcrun_stop_timer(td);
  if (rc != 0) {
    EMSG("stop %s failed, errno: %d", the_event_name, errno);
  }

  TD_GET(ss_state)[self->sel_idx] = STOP;
}
Example #6
0
static void
METHOD_FN(start)
{
  TMSG(ITIMER_CTL, "start %s", the_event_name);

  // the realtime clock needs an extra step to create the timer
  if (use_realtime || use_cputime) {
    thread_data_t *td = hpcrun_get_thread_data();
    if (hpcrun_create_real_timer(td) != 0) {
      EEMSG("Unable to create the timer for %s", the_event_name);
      hpcrun_ssfail_start(the_event_name);
    }
  }

  // itimer is process-wide, so reopen the signal at start time
  if (use_itimer) {
    monitor_real_pthread_sigmask(SIG_UNBLOCK, &timer_mask, NULL);
  }

  hpcrun_restart_timer(self, 1);
}