示例#1
0
void smp_coll_barrier_cond_var(smp_coll_t handle, int flags){
  static gasneti_mutex_t barrier_mutex = GASNETT_MUTEX_INITIALIZER;
  static volatile int phase = 0;
  static volatile unsigned int barrier_count = 0;
  static sem_t sem[2];
  gasneti_mutex_lock(&barrier_mutex);
  { int myphase = phase;
    static volatile int firsttime = 1;
    if (firsttime) {
      gasneti_assert_zeroret(sem_init(&sem[0], 0, 0));
      gasneti_assert_zeroret(sem_init(&sem[1], 0, 0));
      firsttime = 0;
    }
    barrier_count++;
    if (barrier_count < handle->THREADS) {
      gasneti_mutex_unlock(&barrier_mutex); 
      gasneti_assert_zeroret(sem_wait(&sem[myphase]));
    } else {
      int i;
      barrier_count = 0;
      phase = !phase;
      gasneti_mutex_unlock(&barrier_mutex);
      for (i=0; i < (handle->THREADS-1); i++) {
        gasneti_assert_zeroret(sem_post(&sem[myphase]));
      }
    }
  }
}
示例#2
0
void smp_coll_barrier_cond_var(smp_coll_t handle, int flags){
  /* cond variables must be phased on some OS's (HPUX) */
  GASNETI_UNUSED_UNLESS_THREADS
  static struct {
    gasnett_cond_t cond;
    gasnett_mutex_t mutex;
  } barrier[2] = { { GASNETT_COND_INITIALIZER, GASNETT_MUTEX_INITIALIZER },
                   { GASNETT_COND_INITIALIZER, GASNETT_MUTEX_INITIALIZER }};
  static volatile unsigned int barrier_count = 0;
  static volatile int phase = 0;
  const int myphase = phase;
  gasneti_mutex_lock(&(barrier[myphase].mutex));
  barrier_count++;
  if (barrier_count != handle->THREADS) {
    /* CAUTION: changing the "do-while" to a "while" triggers a bug in the SunStudio 2006-08
     * compiler for x86_64.  See http://upc-bugs.lbl.gov/bugzilla/show_bug.cgi?id=1858
     * which includes a link to Sun's own database entry for this issue.
     */
    do {
      gasneti_cond_wait(&(barrier[myphase].cond), &(barrier[myphase].mutex));
    } while (myphase == phase);
  } else {  
    barrier_count = 0;
    phase = !phase;
    gasneti_cond_broadcast(&(barrier[myphase].cond));
  }       
  gasneti_mutex_unlock(&(barrier[myphase].mutex));
}
void
gasnete_fh_request_put(void *_pop, const firehose_request_t *req,
			int allLocalHit)
{
	gasnete_eop_t	*pop = (gasnete_eop_t *) _pop;
	gasnet_node_t	node;

	gasneti_assert(pop != NULL);
	gasneti_assert(pop->src > 0 && pop->dest > 0);
	node = pop->node;
	gasneti_assert(node != gasneti_mynode && node < gasneti_nodes);
	gasneti_assert(pop->len > 0);
	gasneti_assert(req == &(pop->req_remote));

	gasneti_mutex_lock(&gasnetc_lock_gm);
	gasnetc_token_lo_poll();

	GASNETI_TRACE_PRINTF(C, 
	    ("Firehose directed send(%p): (%d,%p) <- (%p,%d)", 
	     (void *) pop, (unsigned) node, (void *) pop->dest, 
	     (void *) pop->src, pop->len));

	#if GASNETI_STATS_OR_TRACE
	if (!allLocalHit)
	    pop->fh_stats = pop->len > 4096 ? fh_many : fh_one;
	#endif

	GASNETC_GM_PUT(
	    _gmc.port, (void *) pop->src, (gm_remote_ptr_t) pop->dest,
	    (unsigned long) pop->len, GM_LOW_PRIORITY,
	    gasnetc_nodeid(node), gasnetc_portid(node),
	    gasnete_fh_callback_put, (void *) pop);
	gasneti_mutex_unlock(&gasnetc_lock_gm);
	return;
}
示例#4
0
static int split_string(char ***split_strs, char *str, char *delim) {
  char *temp=NULL,*copy;
  int ret=0;
  size_t malloc_len = 8;
  static gasneti_mutex_t lock= GASNETI_MUTEX_INITIALIZER;

  copy = gasneti_malloc(sizeof(char)*(strlen(str)+1));
  
  /*since the strtok function is desructive we have to
    create a copy of the string first to preserve the orignal*/
  GASNETE_FAST_UNALIGNED_MEMCPY_CHECK(copy, str, sizeof(char)*(strlen(str)+1));
  gasneti_mutex_lock(&lock);
  *split_strs = (char **) gasneti_malloc(sizeof(char*) * malloc_len);
  temp = strtok(copy, delim);
  while(temp != NULL) {
    if(ret == malloc_len) {
      /*we've run out of space so grow the array by another factor*/
      malloc_len +=malloc_len;
      *split_strs = (char**) gasneti_realloc(*split_strs, sizeof(char*) * malloc_len);
      gasneti_fatalerror("more than 8 params not yet supported");

    }
    (*split_strs)[ret] = temp;
    
    ret++;
    temp=strtok(NULL, delim);
  }
  *split_strs = (char**) gasneti_realloc(*split_strs, sizeof(char*) * ret);
  gasneti_mutex_unlock(&lock);

  return ret;
}
示例#5
0
extern int gasnetc_EP_Create(gex_EP_t           *ep_p,
                             gex_Client_t       client,
                             gex_Flags_t        flags) {
  /* (###) add code here to create an endpoint belonging to the given client */
#if 1 // TODO-EX: This is a stub, which assumes 1 implicit call from ClientCreate
  static gasneti_mutex_t lock = GASNETI_MUTEX_INITIALIZER;
  gasneti_mutex_lock(&lock);
    static int once = 0;
    int prev = once;
    once = 1;
  gasneti_mutex_unlock(&lock);
  if (prev) gasneti_fatalerror("Multiple endpoints are not yet implemented");
#endif

  gasneti_EP_t ep = gasneti_alloc_ep(gasneti_import_client(client), flags, 0);
  *ep_p = gasneti_export_ep(ep);

  { /*  core API handlers */
    gex_AM_Entry_t *ctable = (gex_AM_Entry_t *)gasnetc_get_handlertable();
    int len = 0;
    int numreg = 0;
    gasneti_assert(ctable);
    while (ctable[len].gex_fnptr) len++; /* calc len */
    if (gasneti_amregister(ep->_amtbl, ctable, len, GASNETC_HANDLER_BASE, GASNETE_HANDLER_BASE, 0, &numreg) != GASNET_OK)
      GASNETI_RETURN_ERRR(RESOURCE,"Error registering core API handlers");
    gasneti_assert(numreg == len);
  }

  { /*  extended API handlers */
    gex_AM_Entry_t *etable = (gex_AM_Entry_t *)gasnete_get_handlertable();
    int len = 0;
    int numreg = 0;
    gasneti_assert(etable);
    while (etable[len].gex_fnptr) len++; /* calc len */
    if (gasneti_amregister(ep->_amtbl, etable, len, GASNETE_HANDLER_BASE, GASNETI_CLIENT_HANDLER_BASE, 0, &numreg) != GASNET_OK)
      GASNETI_RETURN_ERRR(RESOURCE,"Error registering extended API handlers");
    gasneti_assert(numreg == len);
  }

  return GASNET_OK;
}
extern
int 
firehose_move_callback(gasnet_node_t node, 
		const firehose_region_t *unpin_list, size_t unpin_num, 
		firehose_region_t *pin_list, size_t pin_num)
{
	int	 i;
	int	locked = GASNETE_GM_IN_UNKNOWN();
	gm_status_t status;

	if (!locked)
		gasneti_mutex_lock(&gasnetc_lock_gm);

	for (i = 0; i < unpin_num; i++) {
		gasneti_assert(unpin_list[i].addr % GASNET_PAGESIZE == 0);
		gasneti_assert(unpin_list[i].len % GASNET_PAGESIZE == 0);
		status = gm_deregister_memory(_gmc.port, 
			  (void *) unpin_list[i].addr, unpin_list[i].len);
		if (status != GM_SUCCESS) 
		    gasneti_fatalerror("gm_deregister_memory() failed for "
		       "page located at %p (%s)", (void*)unpin_list[i].addr, 
		       gm_strerror(status));
		GASNETI_TRACE_PRINTF(C,
		  ("Firehose unpinlocal = %p, %d", (void *) unpin_list[i].addr,
			(int)unpin_list[i].len));
	}
	GASNETI_TRACE_EVENT_VAL(C, FIREHOSE_LOCALUNPIN_PAGES, unpin_num);

	for (i = 0; i < pin_num; i++) {
                int perm_adj = 0;
              retry_register:
		gasneti_assert(pin_list[i].addr % GASNET_PAGESIZE == 0);
		gasneti_assert(pin_list[i].len % GASNET_PAGESIZE == 0);
		status = gm_register_memory(_gmc.port, (void *)
				pin_list[i].addr, pin_list[i].len);
		if (status != GM_SUCCESS) {
                  if (perm_adj) {
		    gasneti_fatalerror("gm_register_memory() failed for "
		       "page located at %p (%s)", (void*)pin_list[i].addr, 
		       gm_strerror(status));
                  } else { /* bug 1036 - GM cannot register read-only data memory */
                    int j, num_pages = pin_list[i].len / GASNET_PAGESIZE;
                    char *p;
                    static char tst = 0;
                    /* check for readability before we mess with mprotect */
		    GASNETI_TRACE_PRINTF(C,("gm_register_memory() failed for "
		       "page located at %p len=%i pages (%s) -- checking readability", 
                       (void*)pin_list[i].addr, num_pages, gm_strerror(status)));
                    p = (void *)pin_list[i].addr;
                    for (j = 0 ; j < num_pages; j++) {
                      tst += *p; /* if you get a seg fault here, it means firehose tried to register unmapped memory */
                      p += GASNET_PAGESIZE;
                    }
                    p = (void *)pin_list[i].addr;
                    for (j = 0 ; j < num_pages; j++) {
		      GASNETI_TRACE_PRINTF(C,("Attempting mprotect for page located at %p", (void*)p));
                      if (mprotect(p, GASNET_PAGESIZE, PROT_READ|PROT_WRITE))
                        gasneti_fatalerror("mprotect failed in firehose_move_callback: %s", strerror(errno));
                      p += GASNET_PAGESIZE;
                    }
                    perm_adj = 1;
                    goto retry_register;
                  }
                }
		GASNETI_TRACE_PRINTF(C,
		  ("Firehose pinlocal = %p, %d", (void *) pin_list[i].addr,
			(int)pin_list[i].len));
	}
	GASNETI_TRACE_EVENT_VAL(C, FIREHOSE_LOCALPIN_PAGES, pin_num);

	if (!locked)
		gasneti_mutex_unlock(&gasnetc_lock_gm);

	return 0;
}
示例#7
0
gasnete_coll_local_tree_geom_t *gasnete_coll_local_tree_geom_fetch(gasnete_coll_tree_type_t type, gasnet_node_t root,  gasnete_coll_team_t team) {
  gasnete_coll_tree_geom_t *geom_cache_head = team->tree_geom_cache_head;
  gasnete_coll_local_tree_geom_t *ret;
  gasnete_coll_tree_geom_t *curr_geom;
  
  
  /*lock here so that only one multiple threads don't try to build it*/
  gasneti_mutex_lock(&team->tree_geom_cache_lock);
  curr_geom = gasnete_coll_tree_geom_fetch_helper(type, team);
  if(curr_geom == NULL) {
    int i;
#if 0
    if(gasneti_mynode ==0) fprintf(stderr, "%d> new tree: %d type %d fanout\n",gasneti_mynode, type.tree_class, type.prams[0]);
#endif
    /* allocate new geometry */
    curr_geom = (gasnete_coll_tree_geom_t *) gasneti_malloc(sizeof(gasnete_coll_tree_geom_t));
    curr_geom->local_views = (gasnete_coll_local_tree_geom_t**) 
    gasneti_malloc(sizeof(gasnete_coll_local_tree_geom_t*)*team->total_ranks);
    for(i=0; i<team->total_ranks; i++) {
      curr_geom->local_views[i] = NULL;
    }
    curr_geom->tree_type = type;
#if 0
    /* Not using the ref_count for now */
    gasneti_weakatomic_set(&(curr_geom->ref_count), 0, 0);
#endif
    /*	curr_geom->root = root; */
    /* link it into the cache*/
    if(geom_cache_head == NULL) {
      /*cache is empty*/
      curr_geom->prev = NULL;
      curr_geom->next = NULL;
      team->tree_geom_cache_head = curr_geom;
      team->tree_geom_cache_tail = curr_geom;
    } else {
      curr_geom->prev = NULL; /* new head */
      curr_geom->next = team->tree_geom_cache_head;
      team->tree_geom_cache_head->prev = curr_geom;
      team->tree_geom_cache_head = curr_geom;
    }
    curr_geom->local_views[root] = gasnete_coll_tree_geom_create_local(type, root, team, curr_geom);
    
    ret = curr_geom->local_views[root];
    
    /* create local view for the root that we request */
  } else {
    /* if it is already allocated for root go ahead and return it ... this should be the fast path*/    
    if(curr_geom->local_views[root] == NULL) {
      curr_geom->local_views[root] = gasnete_coll_tree_geom_create_local(type, root, team, curr_geom);
    }
    ret = curr_geom->local_views[root];
  } 

#ifdef GASNETC_HAVE_AMRDMA  
  /*at the time of this writing no conduits support this yet*/
  if(team->myrank != ret->root) {
    int count = GASNETE_COLL_TREE_GEOM_CHILD_COUNT(ret);
    gasnet_node_t *tmp = gasneti_calloc(1+count, sizeof(gasnet_node_t));
    memcpy(tmp, GASNETE_COLL_TREE_GEOM_CHILDREN(ret), count*sizeof(gasnet_node_t));
    tmp[count] = GASNETE_COLL_TREE_GEOM_PARENT(ret);
    gasnetc_amrdma_init(1+count, tmp);
    gasneti_free(tmp);
  } else {
    gasnetc_amrdma_init(GASNETE_COLL_TREE_GEOM_CHILD_COUNT(ret),
                        GASNETE_COLL_TREE_GEOM_CHILDREN(ret));
  }
#endif

#if 0
  /* Not using the reference counts for now */
  gasneti_weakatomic_increment(&(curr_geom->ref_count), 0);
  gasneti_weakatomic_increment(&(ret->ref_count), 0);

  /*
  fprintf(stderr, "[%u] gasnete_coll_local_tree_geom_fetch: curr_geom->ref_count %u, ret->ref_count %u \n",
          gasnet_mynode(), gasneti_weakatomic_read(&(curr_geom->ref_count), 0),
          gasneti_weakatomic_read(&(ret->ref_count), 0));
  */
#endif

  gasneti_mutex_unlock(&team->tree_geom_cache_lock);
  return ret;
}