Ejemplo n.º 1
0
static void *
__upc_start_pthread (void *arg)
{
  upc_startup_args_p startup_args = arg;
  int thread_id = startup_args->thread_id;
  upc_info_p u = __upc_info;
  int *status_ptr;
  if (!u)
    __upc_fatal ("UPC runtime not initialized");
  /* MYTHREAD is located in thread local storage */
  MYTHREAD = thread_id;
  __upc_affinity_set (u, thread_id);
  /* Perform per thread initialization.  */
  __upc_per_thread_init (u);
  /* Initialize random number generator seed.
     Note: C99 requires an initial seed value of 1, per 7.20.2.2. */
  __upc_srand (1);
  status_ptr = &u->thread_info[thread_id].exit_status;
  __upc_barrier (GUPCR_RUNTIME_BARRIER_ID);
  __upc_pupc_init (&startup_args->argc, &startup_args->argv);
  *status_ptr = GUPCR_MAIN (startup_args->argc, startup_args->argv);
  p_startx (GASP_UPC_COLLECTIVE_EXIT, *status_ptr);
  p_endx (GASP_UPC_COLLECTIVE_EXIT, *status_ptr);
  return status_ptr;
}
Ejemplo n.º 2
0
/* upc_global_exit - exit program with given status, terminate
   all other threads.
 
   The implementation imposes a restriction on exit return codes.
   If the return code has bit 7 (0x80) set, then the exit code will
   be interpreted as the code passed to upc_global_exit() and the
   monitor program will cancel all other executing threads.  */
void
upc_global_exit (int status)
{
  upc_info_p u = __upc_info;
  if (!u)
    __upc_fatal ("UPC runtime not initialized");
  exit ((THREADS > 1) ? ((status & 0x7f) | 0x80) : status);
}
Ejemplo n.º 3
0
void
__upc_exit (int status)
{
  upc_info_p u = __upc_info;
  int *status_ptr;
  int thread_id = MYTHREAD;
  if (!u)
    __upc_fatal ("UPC runtime not initialized");
  __upc_barrier (GUPCR_RUNTIME_BARRIER_ID);
  status_ptr = &u->thread_info[thread_id].exit_status;
  *status_ptr = status;
  pthread_exit (status_ptr);
}
Ejemplo n.º 4
0
/* Calls to exit() are rewritten into calls to __upc_exit()
   by #define in <gcc-upc.h>. Simply perform a upc_barrier and
   then exit the process. Monitor_threads() will pick up
   the returned status code.  */
void
__upc_exit (int status)
{
  upc_info_p u = __upc_info;
  if (!u)
    __upc_fatal ("UPC runtime not initialized");
  __upc_acquire_lock (&u->lock);
  fflush (0);
  fsync (1);
  fsync (2);
  __upc_release_lock (&u->lock);
  __upc_barrier (GUPCR_RUNTIME_BARRIER_ID);
  exit (status);
}
Ejemplo n.º 5
0
void
__upc_affinity_set (upc_info_p u, int thread_id)
{
  const upc_thread_info_p tinfo = &u->thread_info[thread_id];
  switch (u->sched_policy)
    {
    case GUPCR_SCHED_POLICY_CPU:
    case GUPCR_SCHED_POLICY_CPU_STRICT:
      {
	const int sched_affinity = tinfo->sched_affinity;
	cpu_set_t set;
	CPU_ZERO (&set);
	CPU_SET (sched_affinity, &set);
	if (sched_setaffinity (0, sizeof (set), &set))
	  {
	    __upc_fatal ("Scheduling cannot be set");
	  }
      }
      break;
    case GUPCR_SCHED_POLICY_NODE:
      __upc_numa_sched_set (u, thread_id);
      break;
    default:
      /* auto - no scheduling support */
      break;
    }
  /* set memory policy only if we are not AUTO scheduling */
  if ((u->sched_policy != GUPCR_SCHED_POLICY_AUTO) &&
      (u->mem_policy != GUPCR_MEM_POLICY_AUTO))
    __upc_numa_memory_affinity_set (u, thread_id);
#ifdef DEBUG_AFFINITY
  printf ("affinity: %d (%s,%s) scheduling (%d,%d)\n", thread_id,
	  upc_sched_policy_to_string (u->sched_policy),
	  upc_mem_policy_to_string (u->mem_policy),
	  tinfo->sched_affinity, tinfo->mem_affinity);
#endif /* DEBUG_AFFINITY */
}
Ejemplo n.º 6
0
/** 
 * GLIBC backtrace.
 *
 * Show backtrace by using the GLIBC backtrace functionality.
 * Backtrace is improved with the source file/line numbers if
 * libbfd is available.
 *
 * By default backtrace lines are sent to the 'stderr' file
 * descriptor.  However, an environment variable
 * UPC_BACKTRACEFILE can be used to redirect the backtrace
 * to an actual file and it is used as a simple prefix for
 * the backtrace file. For example, if it is set to "/tmp/trace-upc",
 * the actual trace file is going to be "/tmp/trace-upc-PID.MYTHREAD".
 * If empty environment variable is provided, a simple "trace" prefix
 * is used.
 *
 */
void
__upc_backtrace (void)
{
  void *strace[GUPCR_BT_DEPTH_CNT];
  size_t size,i;
  char **strace_str;
  char *file_env;
  int under_upc_main = 1;
  FILE *traceout = stderr;
  upc_info_p u = __upc_info;
  if (!u)
    __upc_fatal ("UPC runtime not initialized");

  file_env = getenv (GUPCR_BACKTRACE_FILE_ENV);
  if (file_env)
    {
      int len = strlen (file_env); 
      char *tracefile = malloc (len + 128);
      if (!tracefile)
        __upc_fatal ("UPC backtrace cannot allocate file name memory");
      if (len)
        strcpy (tracefile, file_env);
      else
        {
	  strcpy (tracefile, "backtrace");
          len = 9;
	}
      len = snprintf (&tracefile[len], 128, ".%d", MYTHREAD);
      traceout = fopen (tracefile, "w");
      if (!traceout)
	__upc_fatal ("Cannot open file for backtrace log");
      free (tracefile);
    }
  else
    fprintf (traceout, "Thread %d backtrace:\n", MYTHREAD);

  /* Use "backtrace" functionality of glibc. */
  size = backtrace (strace, GUPCR_BT_DEPTH_CNT);
# if HAVE_LIBBFD
  strace_str = backtrace_src_symbols (strace, size, __upc_abs_execname);
# else
  strace_str = backtrace_symbols (strace, size);
# endif
  for (i = GUPCR_BT_SKIP_FRAME_CNT; i < size; i++)
    {
      if (under_upc_main)
        {
	  fprintf (traceout, "[%4d][%lld] %s\n", MYTHREAD, 
	      (long long int) (i - GUPCR_BT_SKIP_FRAME_CNT), strace_str[i]);
	  /* Extra info for the barrier. */
	  if ( strstr( strace_str[i], "__upc_wait"))
	    {
	      fprintf (traceout, "[%4d]       BARRIER ID: %d\n", MYTHREAD, 
		       __upc_barrier_id);
	    }
	}
      if (under_upc_main && strstr (strace_str[i], "upc_main"))
        under_upc_main = 0;
    }
  fflush (traceout);
  if (file_env)
    fclose (traceout);
}
Ejemplo n.º 7
0
/* Check for UPC runtime calls from OMP threads.  */
void
__upc_omp_check (void)
{
  if (__upc_omp_master_id != pthread_self ())
    __upc_fatal ("UPC runtime calls are allowed only from UPC threads");;
}