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])); } } } }
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; }
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; }
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; }
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; }