コード例 #1
0
ファイル: tst.c プロジェクト: HPCToolkit/hpctoolkit
static void
METHOD_FN(start)
{
  if (! hpcrun_td_avail()){
    return; // in the unlikely event that we are trying to start, but thread data is unavailable,
            // assume that all sample source ops are suspended.
  }

  TMSG(_TST_CTL,"starting _tst w value = (%d,%d), interval = (%d,%d)",
       itimer.it_interval.tv_sec,
       itimer.it_interval.tv_usec,
       itimer.it_value.tv_sec,
       itimer.it_value.tv_usec);

  if (setitimer(HPCRUN_PROFILE_TIMER, &itimer, NULL) != 0) {
    EMSG("setitimer failed (%d): %s", errno, strerror(errno));
    hpcrun_ssfail_start("_tst");
  }

#ifdef USE_ELAPSED_TIME_FOR_WALLCLOCK
  int ret = time_getTimeCPU(&TD_GET(last_time_us));
  if (ret != 0) {
    EMSG("time_getTimeCPU (clock_gettime) failed!");
    abort();
  }
#endif

  TD_GET(ss_state)[self->sel_idx] = START;
}
コード例 #2
0
ファイル: mem.c プロジェクト: wjcsharp/hpctoolkit
//
// Returns: address of freeable region at the high end,
// else NULL on failure.
//
void *
hpcrun_malloc_freeable(size_t size)
{
  return hpcrun_malloc(size);

  // For now, don't bother with freeable memory.
#if 0
  hpcrun_meminfo_t *mi = &TD_GET(memstore);
  void *addr, *ans;

  size = round_up(size);
  addr = mi->mi_low + size;

  // Recoverable out of memory.
  if (addr >= mi->mi_high) {
    TD_GET(mem_low) = 1;
    TMSG(MALLOC, "%s: size = %ld, failure: temporary out of memory",
	 __func__, size);
    num_failures++;
    return NULL;
  }

  // Low on memory.
  if (addr + low_memsize > mi->mi_high) {
    TD_GET(mem_low) = 1;
    TMSG(MALLOC, "%s: low on memory, setting epoch flush flag", __func__);
  }

  ans = mi->mi_low;
  mi->mi_low = addr;
  total_freeable += size;
  TMSG(MALLOC, "%s: size = %ld, addr = %p", __func__, size, addr);
  return ans;
#endif
}
コード例 #3
0
ファイル: mem.c プロジェクト: wjcsharp/hpctoolkit
// Reclaim the freeable CCT memory at the low end.
void
hpcrun_reclaim_freeable_mem(void)
{
  hpcrun_meminfo_t *mi = &TD_GET(memstore);

  mi->mi_low = mi->mi_start;
  TD_GET(mem_low) = 0;
  num_reclaims++;
  TMSG(MALLOC, "%s: %d", __func__, num_reclaims);
}
コード例 #4
0
ファイル: unw-throw.c プロジェクト: wjcsharp/hpctoolkit
void
hpcrun_unw_throw(void)
{
  if (DEBUG_NO_LONGJMP) return;

  if (hpcrun_below_pmsg_threshold()) {
    hpcrun_bt_dump(TD_GET(btbuf_cur), "PARTIAL");
  }

  hpcrun_up_pmsg_count();

  sigjmp_buf_t *it = &(TD_GET(bad_unwind));
  (*hpcrun_get_real_siglongjmp())(it->jb, 9);
}
コード例 #5
0
ファイル: hpcrun_dlfns.c プロジェクト: wjcsharp/hpctoolkit
void 
hpcrun_pre_dlopen(const char *path, int flags)
{
  hpcrun_dlopen_write_lock();
  atomic_add_i64(&num_dlopen_pending, 1L);
  TD_GET(inside_dlfcn) = true;
}
コード例 #6
0
ファイル: none.c プロジェクト: wjcsharp/hpctoolkit
static void
METHOD_FN(start)
{
  TMSG(NONE_CTL,"starting NONE");

  TD_GET(ss_state)[self->sel_idx] = START;
}
コード例 #7
0
ファイル: x86-unwind.c プロジェクト: wjcsharp/hpctoolkit
static void 
help_simulate_segv(bool no_backtrace)
{
  if (DEBUG_NO_LONGJMP) return;

  if (no_backtrace) {
    return;
  }
  if (hpcrun_below_pmsg_threshold()) {
    hpcrun_bt_dump(TD_GET(btbuf_cur), "DROP");
  }

  hpcrun_up_pmsg_count();

  sigjmp_buf_t *it = &(TD_GET(bad_unwind));
  (*hpcrun_get_real_siglongjmp())(it->jb, 9);
}
コード例 #8
0
ファイル: itimer.c プロジェクト: HPCToolkit/hpctoolkit
// 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;
}
コード例 #9
0
ファイル: tst.c プロジェクト: HPCToolkit/hpctoolkit
static void
METHOD_FN(stop)
{
  int rc;

  rc = setitimer(HPCRUN_PROFILE_TIMER, &zerotimer, NULL);

  TMSG(ITIMER_CTL,"stopping _tst");
  TD_GET(ss_state)[self->sel_idx] = STOP;
}
コード例 #10
0
void
hpcrun_pmsg(const char *tag, const char *fmt, ...)
{
#ifdef SINGLE_THREAD_LOGGING
  if ( getenv("OT") && (TD_GET(core_profile_trace_data.id) != THE_THREAD)) {
    return;
  }
#endif // SINGLE_THREAD_LOGGING
  va_list_box box;
  va_list_box_start(box, fmt);
  hpcrun_write_msg_to_log(false, true, tag, fmt, &box);
}
コード例 #11
0
ファイル: hpcrun_dlfns.c プロジェクト: wjcsharp/hpctoolkit
// We can't downgrade the lock during fnbounds_unmap_closed_dsos()
// because it acquires the fnbounds lock before the dl-iterate lock,
// and that is a LOR with sampling.
//
void
hpcrun_post_dlclose(void *handle, int ret)
{
  int outermost = (dlopen_num_writers == 1);

  TMSG(LOADMAP, "dlclose: handle = %p", handle);
  fnbounds_unmap_closed_dsos();
  if (outermost) {
    TD_GET(inside_dlfcn) = false;
  }
  hpcrun_dlopen_write_unlock();
}
コード例 #12
0
ファイル: hpcrun_dlfns.c プロジェクト: wjcsharp/hpctoolkit
// It's safe to downgrade the lock during fnbounds_map_open_dsos()
// because it acquires the dl-iterate lock before the fnbounds lock,
// and that order is consistent with sampling.  Note: can only
// downgrade the lock on the last (outermost) dlopen.
//
void 
hpcrun_dlopen(const char *module_name, int flags, void *handle)
{
  int outermost = (dlopen_num_writers == 1);

  TMSG(LOADMAP, "dlopen: handle = %p, name = %s", handle, module_name);
  if (outermost) {
    hpcrun_dlopen_downgrade_lock();
  }
  fnbounds_map_open_dsos();
  atomic_add_i64(&num_dlopen_pending, -1L);
  if (outermost) {
    TD_GET(inside_dlfcn) = false;
    hpcrun_dlopen_read_unlock();
  } else {
    hpcrun_dlopen_write_unlock();
  }
}
コード例 #13
0
ファイル: itimer.c プロジェクト: HPCToolkit/hpctoolkit
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;
}
コード例 #14
0
ファイル: tst.c プロジェクト: HPCToolkit/hpctoolkit
static int
_tst_signal_handler(int sig, siginfo_t* siginfo, void* context)
{
  // If the interrupt came from inside our code, then drop the sample
  // and return and avoid any MSG.
  void* pc = hpcrun_context_pc(context);
  if (! hpcrun_safe_enter_async(pc)) {
    hpcrun_stats_num_samples_blocked_async_inc();
  }
  else {
    TMSG(_TST_HANDLER,"_Tst sample event");

    uint64_t metric_incr = 1; // default: one time unit
#ifdef USE_ELAPSED_TIME_FOR_WALLCLOCK
    uint64_t cur_time_us;
    int ret = time_getTimeCPU(&cur_time_us);
    if (ret != 0) {
      EMSG("time_getTimeCPU (clock_gettime) failed!");
      abort();
    }
    metric_incr = cur_time_us - TD_GET(last_time_us);
#endif

    int metric_id = hpcrun_event2metric(&__tst_obj, _TST_EVENT);
    hpcrun_sample_callpath_w_bt(context, metric_id, metric_incr, NULL, NULL, 0);
  }
  if (hpcrun_is_sampling_disabled()) {
    TMSG(SPECIAL, "No _tst restart, due to disabled sampling");
    return 0;
  }

#ifdef RESET_ITIMER_EACH_SAMPLE
  METHOD_CALL(&__tst_obj, start);
#endif

  return 0; /* tell monitor that the signal has been handled */
}
コード例 #15
0
ファイル: none.c プロジェクト: wjcsharp/hpctoolkit
static void
METHOD_FN(stop)
{
  TMSG(NONE_CTL,"stopping NONE");
  TD_GET(ss_state)[self->sel_idx] = STOP;
}
コード例 #16
0
ファイル: itimer.c プロジェクト: HPCToolkit/hpctoolkit
static int
itimer_signal_handler(int sig, siginfo_t* siginfo, void* context)
{
  static bool metrics_finalized = false;
  sample_source_t *self = &_itimer_obj;

  // if sampling is suppressed for this thread, restart timer, & exit
  if (hpcrun_thread_suppress_sample) {
    TMSG(ITIMER_HANDLER, "thread sampling suppressed");
    hpcrun_restart_timer(self, 1);
    return 0;
  }

  // If we got a wallclock signal not meant for our thread, then drop the sample
  if (! wallclock_ok) {
    EMSG("Received itimer signal, but thread not initialized");
  }
  // If the interrupt came from inside our code, then drop the sample
  // and return and avoid any MSG.
  void* pc = hpcrun_context_pc(context);
  if (! hpcrun_safe_enter_async(pc)) {
    hpcrun_stats_num_samples_blocked_async_inc();
    if (! hpcrun_is_sampling_disabled()) {
      hpcrun_restart_timer(self, 0);
    }
    // tell monitor the signal has been handled.
    return 0;
  }

  // Ensure metrics are finalized.
  if (!metrics_finalized) {
    hpcrun_finalize_metrics();
    metrics_finalized = true;
  }

  TMSG(ITIMER_HANDLER,"Itimer sample event");

  uint64_t metric_incr = 1; // default: one time unit

#if defined (USE_ELAPSED_TIME_FOR_WALLCLOCK) 
  uint64_t cur_time_us = 0;
  int ret = time_getTimeReal(&cur_time_us);
  if (ret != 0) {
    EMSG("time_getTimeReal (clock_gettime) failed!");
    monitor_real_abort();
  }
  metric_incr = cur_time_us - TD_GET(last_time_us);
#endif

  int metric_id = hpcrun_event2metric(self, ITIMER_EVENT);
  sample_val_t sv = hpcrun_sample_callpath(context, metric_id, metric_incr,
					    0/*skipInner*/, 0/*isSync*/);
  blame_shift_apply(metric_id, sv.sample_node, metric_incr);

  if (hpcrun_is_sampling_disabled()) {
    TMSG(ITIMER_HANDLER, "No itimer restart, due to disabled sampling");
  }
  else {
    hpcrun_restart_timer(self, 1);
  }

  hpcrun_safe_exit();

  return 0; /* tell monitor that the signal has been handled */
}
コード例 #17
0
int
hpcrun_is_handling_sample(void)
{
  return (TD_GET(handling_sample) == 0xDEADBEEF);
}
コード例 #18
0
ファイル: mem.c プロジェクト: wjcsharp/hpctoolkit
//
// Returns: address of non-freeable region at the high end,
// else NULL on failure.
//
void *
hpcrun_malloc(size_t size)
{
  hpcrun_meminfo_t *mi;
  void *addr;

  // Lush wants to ask for 0 bytes and get back NULL.
  if (size == 0) {
    return NULL;
  }

  mi = &TD_GET(memstore);
  size = round_up(size);

  // For a large request that doesn't fit within the existing
  // memstore, mmap a separate region for it.
  if (size > memsize/5 && allow_extra_mmap
      && (mi->mi_start == NULL || size > mi->mi_high - mi->mi_low)) {
    addr = hpcrun_mmap_anon(size);
    if (addr == NULL) {
      if (! out_of_mem_mesg) {
	EMSG("%s: out of memory, shutting down sampling", __func__);
	out_of_mem_mesg = 1;
      }
      hpcrun_disable_sampling();
      num_failures++;
      return NULL;
    }
    TMSG(MALLOC, "%s: size = %ld, addr = %p", __func__, size, addr);
    total_non_freeable += size;
    return addr;
  }

  // See if we need to allocate a new memstore.
  if (mi->mi_start == NULL
      || mi->mi_high - mi->mi_low < low_memsize
      || mi->mi_high - mi->mi_low < size) {
    if (allow_extra_mmap) {
      hpcrun_make_memstore(mi, 0);
    } else {
      if (! out_of_mem_mesg) {
	EMSG("%s: out of memory, shutting down sampling", __func__);
	out_of_mem_mesg = 1;
      }
      hpcrun_disable_sampling();
    }
  }

  // There is no memstore, for some reason.
  if (mi->mi_start == NULL) {
    TMSG(MALLOC, "%s: size = %ld, failure: no memstore",
	 __func__, size);
    num_failures++;
    return NULL;
  }

  // Not enough space in existing memstore.
  addr = mi->mi_high - size;
  if (addr <= mi->mi_low) {
    TMSG(MALLOC, "%s: size = %ld, failure: out of memory",
	 __func__, size);
    num_failures++;
    return NULL;
  }

  // Success
  mi->mi_high = addr;
  total_non_freeable += size;
  TMSG(MALLOC, "%s: size = %ld, addr = %p", __func__, size, addr);
  return addr;
}
コード例 #19
0
ファイル: agent-pthread.c プロジェクト: wjcsharp/hpctoolkit
extern bool
LUSHI_do_metric(uint64_t incrMetricIn,
		bool* doMetric, bool* doMetricIdleness,
		uint64_t* incrMetric, double* incrMetricIdleness)
{
  lushPthr_t* pthr = &TD_GET(pthr_metrics);
  bool isWorking = pthr->is_working;

  if (isWorking) {
#if (LUSH_PTHR_FN_TY == 1)
    // NOTE: pthr->idleness is only changed when this thread is not working
    *doMetric = true;
    *doMetricIdleness = (pthr->idleness > 0);
    *incrMetric = incrMetricIn;
    *incrMetricIdleness = pthr->idleness;
    pthr->idleness = 0;
#elif (LUSH_PTHR_FN_TY == 2)
    bool is_working_lock = lushPthr_isWorking_lock(pthr);
    
    double num_working      = *(pthr->ps_num_working);
    double num_working_lock = *(pthr->ps_num_working_lock);
    double num_idle_cond    = MAX(0, *(pthr->ps_num_idle_cond)); // timing!

    // INVARIANT: Since this thread is working, it is either working
    // while locked or it is working as 'other' (within a condition
    // variable critical section or without a lock).
    double idleness = 0.0;
    if (is_working_lock) {
      // -----------------------------------------------------
      // is_working_lock() : num_idle_lock / num_working_lock
      // -----------------------------------------------------
      double num_idle = (*(pthr->ps_num_threads) - num_working);
      double num_idle_lock = MAX(0, num_idle - num_idle_cond);
      num_working_lock = MAX(1, num_working_lock); // timing windows
      idleness = (num_idle_lock / num_working_lock);
    }
    else {
      // -----------------------------------------------------
      // is_working_cond() || is_working : num_idle_cond / num_working_othr
      // -----------------------------------------------------
      // INVARIANT: (num_working - num_working_lock) should always be > 0
      double num_working_othr = MAX(1, num_working - num_working_lock);
      idleness = (num_idle_cond / num_working_othr);
    }

    *doMetric = true;
    *doMetricIdleness = true;
    *incrMetric = incrMetricIn;
    *incrMetricIdleness = (double)incrMetricIn * idleness;
#elif (LUSH_PTHR_FN_TY == 3)
    // Same as 1
    *doMetric = true;
    *doMetricIdleness = (pthr->idleness > 0);
    *incrMetric = incrMetricIn;
    *incrMetricIdleness = pthr->idleness;
    pthr->idleness = 0;
#else
#  error "agent-pthread.c!"
#endif
  }
  else {
#if (LUSH_PTHR_FN_TY == 1)
    *doMetric = true;
    *doMetricIdleness = true;
    *incrMetric = 0;
    *incrMetricIdleness = (double)incrMetricIn;
#elif (LUSH_PTHR_FN_TY == 2)
    *doMetric = false;
    *doMetricIdleness = false;
    //*incrMetric = 0;
    //*incrMetricIdleness = 0.0;
#elif (LUSH_PTHR_FN_TY == 3)
    if (pthr->syncObjData) {
      // INVARIANT: spin waiting on pthr->syncObjData
      hpcrun_atomicAdd(&pthr->syncObjData->idleness, incrMetricIn);
    }
    *doMetric = false;
    *doMetricIdleness = false;
#else
#  error "agent-pthread.c!"
#endif
  }
  return *doMetric;
}
コード例 #20
0
ファイル: hpcrun_dlfns.c プロジェクト: wjcsharp/hpctoolkit
void
hpcrun_dlclose(void *handle)
{
  hpcrun_dlopen_write_lock();
  TD_GET(inside_dlfcn) = true;
}