void vt_fork(pid_t pid)
{
  vt_libassert(pid != -1);

  fork_performed = 1;

  /* child process ... */
  if ( pid == 0 )
  {
    vt_my_ptrace = vt_my_trace;
    vt_my_trace = get_new_trcid();

    vt_error_pid(vt_my_trace);

    /* reset VampirTrace for new child process */
    vt_reset();
  }
  /* parent process ... */
  else
  {
    vt_error_pid(vt_my_trace);

    /* add new pid to child vector */
    childv_add(pid);
  }
}
static void idle_tid_list_push_back(uint32_t ptid, uint32_t tid)
{
  IdleThreadIdListEntryT* idle_tid;

  vt_libassert(ptid < VTThrdMaxNum);

  /* create new list entry */
  idle_tid = (IdleThreadIdListEntryT*)calloc(1,
               sizeof(IdleThreadIdListEntryT));
  if (idle_tid == NULL)
    vt_error();

  idle_tid->tid = tid;

  /* append new entry to list */
  if (idleThreadIds[ptid].last)
  {
    idleThreadIds[ptid].last->next = idle_tid;
    idleThreadIds[ptid].last = idle_tid;
  }
  else
  {
    idleThreadIds[ptid].first = idleThreadIds[ptid].last = idle_tid;
  }

  /* increment size of list */
  idleThreadIds[ptid].size++;
}
Example #3
0
void vt_mpi_register_remain()
{
  vt_libassert( mpi_fid != (uint32_t)-1 );

  /* include generated function registry */
# include "vt_mpireg.gen.c"
}
static void maybe_register_new_thread(VTThrd * thrd, uint32_t tid) {
  struct vt_plugin_cntr_defines * plugin_cntr_defines;
  vt_libassert(thrd!=NULL);
  /* "register" a thread */
  if (thrd->plugin_cntr_defines == NULL) {
    thrd->plugin_cntr_defines
        = calloc(1, sizeof(struct vt_plugin_cntr_defines));
    vt_libassert(thrd->plugin_cntr_defines!=NULL);
    plugin_cntr_defines
        = (struct vt_plugin_cntr_defines *) thrd->plugin_cntr_defines;
    plugin_cntr_defines->counters = calloc(VT_PLUGIN_CNTR_SYNCH_TYPE_MAX,
        sizeof(struct vt_plugin_single_counter *));
    /* number of counters of type */
    plugin_cntr_defines->size_of_counters = calloc(
        VT_PLUGIN_CNTR_SYNCH_TYPE_MAX, sizeof(uint32_t));
    /* single elements in vectors */
  }
}
uint32_t vt_plugin_cntr_get_num_synch_metrics(VTThrd * thrd) {
  uint32_t num = 0;
  vt_libassert(thrd != NULL);
  if (thrd->plugin_cntr_defines == NULL)
    return 0;
  num = ((struct vt_plugin_cntr_defines *)(thrd->plugin_cntr_defines))
      ->size_of_counters[VT_PLUGIN_CNTR_SYNCH];
  return num;
}
Example #6
0
void vt_getcpu_init()
{
  vt_libassert(vt_misc_cgid != 0);

  /* write counter definition */
  vt_getcpu_cid = vt_def_counter(VT_CURRENT_THREAD, "CPU_ID", "#",
                                 VT_CNTR_ABS | VT_CNTR_NEXT,
                                 vt_misc_cgid, 0);
}
Example #7
0
void VT_Dyn_start(uint32_t index, const char* name, const char* fname,
                  uint32_t lno, uint32_t loop)
{
  uint64_t time;
  uint32_t* rid;

  vt_libassert(index < VT_MAX_DYNINST_REGIONS);

  /* Ignore events if VT is initializing */
  if( !dyn_init && !vt_is_alive ) return;

  /* If not yet initialized, initialize VampirTrace */
  if ( dyn_init )
  {
    VT_MEMHOOKS_OFF();
    dyn_init = 0;
    rtab = (uint32_t*)calloc(VT_MAX_DYNINST_REGIONS, sizeof(uint32_t));
    if ( rtab == NULL )
      vt_error();
    vt_open();
    vt_comp_finalize = VT_Dyn_finalize;
    VT_MEMHOOKS_ON();
  }

  /* If VampirTrace already finalized, return */
  if ( !vt_is_alive ) return;

  VT_MEMHOOKS_OFF();

  time = vt_pform_wtime();

  /* Get region identifier
   */
  rid = &(rtab[index]);
  if ( *rid == 0 )
  {
    /* If region entered the first time, register region
     */
#if (defined(VT_MT) || defined(VT_HYB))
    VTTHRD_LOCK_IDS();
    if ( *rid == 0 )
      *rid = register_region(name, fname, lno, loop);
    VTTHRD_UNLOCK_IDS();
#else /* VT_MT || VT_HYB */
    *rid = register_region(name, fname, lno, loop);
#endif /* VT_MT || VT_HYB */
  }

  /* Write enter record */
  vt_enter(VT_CURRENT_THREAD, &time, *rid);

  VT_MEMHOOKS_ON();
}
char* vt_fork_get_trcid_filename()
{
  char* filename;

  vt_libassert(trcid_filename[0] != '\0');

  filename = strdup(trcid_filename);
  if ( filename == NULL )
    vt_error();

  return filename;
}
void __func_trace_exit(char* name, char* fname, int lno)
#endif
{
  HashNode *hn;
  uint32_t tid;
  uint64_t time;

  /* -- if VampirTrace already finalized, return -- */
  if ( !vt_is_alive ) return;

# if __IBMC__ > 1100
  vt_libassert(*ihn != NULL);

  /* -- ignore IBM OMP runtime functions -- */
  if ( *ihn == &ignored_func ) return;

  hn = *ihn;
# else /* __IBMC__ */
  /* -- ignore IBM OMP runtime functions -- */
  if ( ( strchr(name, '@') != NULL ) || (strchr(name, '$') != NULL) )
    return;

  hn = hash_get((long) name);
  vt_libassert(hn != NULL);
# endif /* __IBMC__ */

  /* -- get calling thread id -- */
  GET_THREAD_ID(tid);

  VT_SUSPEND_MALLOC_TRACING(tid);

  time = vt_pform_wtime();

  /* -- write exit record -- */
  vt_exit(tid, &time);

  VT_RESUME_MALLOC_TRACING(tid);
}
uint32_t vt_fork_get_num_childs_tot()
{
  uint32_t nchilds_tot;

  /* any fork performed? (trace-id file exists?) */
  if ( fork_performed )
  {
    int fd;
    char tmp[16] = "";

    vt_libassert(trcid_filename[0] != '\0');

    VT_SUSPEND_IO_TRACING(VT_CURRENT_THREAD);

    /* open temp. id file for reading */
    if ( (fd = open(trcid_filename, O_RDONLY)) == -1 )
      vt_error_msg("Cannot open file %s: %s", trcid_filename, strerror(errno));

    /* read current trace id */
    if ( read(fd, tmp, 16) == -1 )
      vt_error_msg("Cannot read file %s: %s", trcid_filename, strerror(errno));

    vt_libassert(tmp[0] != '\0');
    nchilds_tot = atoi(tmp);
    vt_libassert(nchilds_tot > 0);

    /* close temp. id file */
    close(fd);

    VT_RESUME_IO_TRACING(VT_CURRENT_THREAD);
  }
  else
  {
    nchilds_tot = 0;
  }
  
  return nchilds_tot;
}
static uint32_t idle_tid_list_pop_front(uint32_t ptid)
{
  uint32_t tid;
  IdleThreadIdListEntryT* tmp;

  vt_libassert(ptid < VTThrdMaxNum);
  vt_libassert(idleThreadIds[ptid].size > 0);

  /* get thread-ID from the first list entry */
  tid = idleThreadIds[ptid].first->tid;

  /* remove first list entry */
  tmp = idleThreadIds[ptid].first;
  if (idleThreadIds[ptid].first == idleThreadIds[ptid].last)
    idleThreadIds[ptid].first = idleThreadIds[ptid].last = NULL;
  else
    idleThreadIds[ptid].first = tmp->next;
  free(tmp);

  /* decrement size of list */
  idleThreadIds[ptid].size--;

  return tid;
}
uint32_t VTThrd_getThreadId()
{
  uint32_t *tid;

  /* get thread-ID from thread-specific data */
  tid = (uint32_t*)pthread_getspecific(pthreadKey);

  /* by calling pthread_exit() in main() the thread-specific data for
     the master thread can already be destroyed at this point; if this
     happens return zero (thread-ID of the master thread) */
  if (tid == NULL && masterThreadTerminated)
    return 0;
  else
    vt_libassert(tid != NULL);

  return *tid;
}
Example #13
0
void vt_win_create( MPI_Win win, MPI_Comm comm )
{
  MPI_Group group;

  /* check if window already exists */
  if (win_search( win ) == (uint32_t)-1)
    {
      uint32_t wid;

#if (defined(VT_MT) || defined(VT_HYB))
      VTTHRD_LOCK_IDS();
#endif /* VT_MT || VT_HYB */
      wid = vt_get_curid();
#if (defined(VT_MT) || defined(VT_HYB))
      VTTHRD_UNLOCK_IDS();
#endif /* VT_MT || VT_HYB */

      /* ask for group of win and register them */

      PMPI_Win_get_group(win, &group);
      vt_libassert(group != MPI_GROUP_NULL);
      vt_group_create(group);

      /* enter win in wins[] array */

      if( free_win != (uint32_t)-1 )
        {
          wins[free_win].win  = win;
          wins[free_win].comm = comm;
          wins[free_win].gid  = vt_group_id(group);
          wins[free_win].wid  = wid;
        }
      else
        {
          /* raise maximum number of windows, if necessary */
          if (last_win == max_wins)
            RAISE_MAX(wins, max_wins, struct VTWin);

          wins[last_win].win  = win;
          wins[last_win].comm = comm;
          wins[last_win].gid  = vt_group_id(group);
          wins[last_win].wid  = wid;
          last_win++;
        }
    }
}
Example #14
0
void VT_Dyn_end(uint32_t index)
{
  uint64_t time;

  vt_libassert(index < VT_MAX_DYNINST_REGIONS);

  /* If VampirTrace already finalized, return */
  if ( !vt_is_alive ) return;

  /* If region id isn't present, return */
  if ( rtab[index] == 0 ) return;

  VT_MEMHOOKS_OFF();

  time = vt_pform_wtime();

  /* Write exit record */
  vt_exit(VT_CURRENT_THREAD, &time);

  VT_MEMHOOKS_ON();
}
static int get_new_trcid()
{
  int new_trcid;
  int fd;
  int8_t tmp_len;
  struct flock fl;
  char tmp[10] = "";
  uint8_t do_unlock = 1;

  vt_libassert(trcid_filename[0] != '\0');

  VT_SUSPEND_IO_TRACING(VT_CURRENT_THREAD);

  /* open/create temp. id file */
  if ( (fd = open(trcid_filename,
		  (O_RDWR | O_CREAT),
		  (S_IRUSR | S_IWUSR))) == -1 )
    vt_error_msg("Cannot open file %s: %s", trcid_filename, strerror(errno));

  /* lock temp. id file */
  fl.l_type = F_WRLCK; fl.l_whence = SEEK_SET; fl.l_start = 0; fl.l_len = 0;
  if (fcntl(fd, F_SETLKW, &fl) == -1)
  {
    do_unlock = 0;
    vt_warning("Cannot lock file %s: %s", trcid_filename, strerror(errno));
  }

  /* read current trace id */
  if ( read(fd, tmp, 9) == -1 )
    vt_error_msg("Cannot read file %s: %s", trcid_filename, strerror(errno));
  tmp[9] = '\0';

  if ( tmp[0] == '\0' )
    new_trcid = 1;             /* set trace id to 1, if file is empty */
  else
    new_trcid = atoi(tmp) + 1; /* increment trace id */

  /* write new trace id */
  lseek(fd, 0, SEEK_SET);
  snprintf(tmp, sizeof(tmp)-1, "%i\n", new_trcid);
  tmp_len = strlen( tmp );
  if( tmp_len > write( fd, tmp, tmp_len ) ){
    vt_error_msg( "Failed to write to file %s: %s", trcid_filename,strerror(errno) );
  }

  /* unlock temp. id file */
  if ( do_unlock )
  {
    fl.l_type = F_UNLCK;
    if ( fcntl(fd, F_SETLK, &fl) == -1 )
      vt_error_msg("Cannot unlock file %s: %s", trcid_filename, strerror(errno));
  }

  /* close temp. id file */
  close(fd);

  vt_cntl_msg(2, "Updated trace-id in %s to %i", trcid_filename, new_trcid);

  VT_RESUME_IO_TRACING(VT_CURRENT_THREAD);

  return new_trcid;
}
void VTThrd_unlock(VTThrdMutex** mutex)
{
  vt_libassert(*mutex != NULL);

  omp_unset_lock(&((*mutex)->m));
}
uint32_t VTThrd_getThreadId()
{
  vt_libassert(threadId != VT_NO_ID);
  return threadId;
}
/* may be called per thread */
void vt_plugin_cntr_write_post_mortem(VTThrd * thrd) {
  uint32_t counter_index;
  uint64_t * counter_current_indices;
  vt_plugin_cntr_timevalue ** time_values_by_counter = NULL;
  uint32_t number_of_counters;
  uint64_t * number_of_values_by_counter;
  uint64_t dummy_time;
  uint32_t tid;
  struct vt_plugin_single_counter current_counter;
  struct vt_plugin_cntr_defines * plugin_cntr_defines =
      (struct vt_plugin_cntr_defines *) thrd->plugin_cntr_defines;
  if (plugin_cntr_defines == NULL)
    return;

  if (plugin_cntr_defines->size_of_counters[VT_PLUGIN_CNTR_ASYNCH_POST_MORTEM]
      == 0)
    return;
  if (VTTHRD_TRACE_STATUS(thrd) != VT_TRACE_ON)
    return;
  for (tid=0;tid<VTThrdn;tid++)
    if ( VTThrdv[tid] == thrd )
      break;
  if ( tid == VTThrdn ){
    vt_warning("Can not determine internal TID when gathering post-mortem counters");
    return;
  }
  /* for all post_mortem counters */
  number_of_counters
    = plugin_cntr_defines->size_of_counters[VT_PLUGIN_CNTR_ASYNCH_POST_MORTEM];
  dummy_time = vt_pform_wtime();
  /* set flag for writing post mortem counters; prevents writing of flush
   * enter/exit event when flushing */
  thrd->plugin_cntr_writing_post_mortem = 1;
  /* we assume that for each counter (not plugin),
   * the data is monotonically increasing */
  /* for all counters of this thread */

  time_values_by_counter = calloc(number_of_counters, sizeof(*time_values_by_counter));
  vt_libassert(time_values_by_counter);
  number_of_values_by_counter = calloc(number_of_counters, sizeof(*number_of_values_by_counter));
  vt_libassert(number_of_values_by_counter);
  for (counter_index = 0;
       counter_index < number_of_counters;
       counter_index++) {
    current_counter
        = plugin_cntr_defines->counters[VT_PLUGIN_CNTR_ASYNCH_POST_MORTEM][counter_index];
    /* get data */
    number_of_values_by_counter[counter_index] = current_counter.getAllValues(
        current_counter.from_plugin_id, &(time_values_by_counter[counter_index]));
    if (time_values_by_counter[counter_index] == NULL) {
      free(time_values_by_counter);
      free(number_of_values_by_counter);
      return;
    }
  }
  /* initialized with 0! */
  counter_current_indices = calloc(number_of_counters, sizeof(*counter_current_indices));
  vt_libassert(counter_current_indices);
  while (1) {
	vt_plugin_cntr_timevalue *min_tvp = NULL;
	uint32_t min_counter;
    for (counter_index = 0;
	     counter_index < number_of_counters;
	     counter_index++)
    {
      /*
       * TODO optimize for "nice" plugins by looking if the "next" counter has the
       * _same_ timestamp (so there cannot be anyone else with a smaller one
       */
	  vt_plugin_cntr_timevalue *tvp;
	  if (counter_current_indices[counter_index] >= number_of_values_by_counter[counter_index]) {
		continue;
	  }
	  tvp = &(time_values_by_counter[counter_index][counter_current_indices[counter_index]]);
      if (!min_tvp || tvp->timestamp < min_tvp->timestamp) {
        min_tvp = tvp;
        min_counter = counter_index;
      }
	}
    if (min_tvp == NULL) {
      /* we are done */
      break;
    }
    current_counter
        = plugin_cntr_defines->counters[VT_PLUGIN_CNTR_ASYNCH_POST_MORTEM][min_counter];
    WRITE_ASYNCH_DATA(thrd, tid, current_counter, *min_tvp, &dummy_time);
    counter_current_indices[min_counter]++;
  }
  free(time_values_by_counter);
  free(counter_current_indices);
  free(number_of_values_by_counter);
  /* unset flag for writing post mortem counters */
  thrd->plugin_cntr_writing_post_mortem = 0;
}
void VTThrd_unlock(VTThrdMutex** mutex)
{
  vt_libassert(*mutex != NULL);

  pthread_mutex_unlock(&((*mutex)->m));
}
static uint32_t idle_tid_list_size(uint32_t ptid)
{
  vt_libassert(ptid < VTThrdMaxNum);
  return idleThreadIds[ptid].size;
}