extern void gasneti_vis_progressfn(void) { GASNETE_THREAD_LOOKUP /* TODO: remove this lookup */ gasnete_vis_threaddata_t *td = GASNETE_VIS_MYTHREAD; gasneti_vis_op_t **lastp = &(td->active_ops); if (td->progressfn_active) return; /* prevent recursion */ td->progressfn_active = 1; for (lastp = &(td->active_ops); *lastp; ) { gasneti_vis_op_t * const visop = *lastp; #ifdef GASNETE_VIS_PROGRESSFN_EXTRA GASNETE_VIS_PROGRESSFN_EXTRA(visop, lastp) #endif switch (visop->type) { #ifdef GASNETE_PUTV_GATHER_SELECTOR case GASNETI_VIS_CAT_PUTV_GATHER: if (gasnete_try_syncnb(visop->handle) == GASNET_OK) { /* TODO: remove recursive poll */ GASNETE_VISOP_SIGNAL_AND_FREE(visop, 0); } break; #endif #ifdef GASNETE_GETV_SCATTER_SELECTOR case GASNETI_VIS_CAT_GETV_SCATTER: if (gasnete_try_syncnb(visop->handle) == GASNET_OK) { gasnet_memvec_t const * const savedlst = (gasnet_memvec_t const *)(visop + 1); void const * const packedbuf = savedlst + visop->count; gasnete_memvec_unpack(visop->count, savedlst, packedbuf, 0, (size_t)-1); GASNETE_VISOP_SIGNAL_AND_FREE(visop, 1); } break; #endif #ifdef GASNETE_PUTI_GATHER_SELECTOR case GASNETI_VIS_CAT_PUTI_GATHER: if (gasnete_try_syncnb(visop->handle) == GASNET_OK) { GASNETE_VISOP_SIGNAL_AND_FREE(visop, 0); } break; #endif #ifdef GASNETE_GETI_SCATTER_SELECTOR case GASNETI_VIS_CAT_GETI_SCATTER: if (gasnete_try_syncnb(visop->handle) == GASNET_OK) { void * const * const savedlst = (void * const *)(visop + 1); void const * const packedbuf = savedlst + visop->count; gasnete_addrlist_unpack(visop->count, savedlst, visop->len, packedbuf, 0, (size_t)-1); GASNETE_VISOP_SIGNAL_AND_FREE(visop, 1); } break; #endif #ifdef GASNETE_PUTS_GATHER_SELECTOR case GASNETI_VIS_CAT_PUTS_GATHER: if (gasnete_try_syncnb(visop->handle) == GASNET_OK) { GASNETE_VISOP_SIGNAL_AND_FREE(visop, 0); } break; #endif #ifdef GASNETE_GETS_SCATTER_SELECTOR case GASNETI_VIS_CAT_GETS_SCATTER: if (gasnete_try_syncnb(visop->handle) == GASNET_OK) { size_t stridelevels = visop->len; size_t * const savedstrides = (size_t *)(visop + 1); size_t * const savedcount = savedstrides + stridelevels; void * const packedbuf = (void *)(savedcount + stridelevels + 1); gasnete_strided_unpack_all(visop->addr, savedstrides, savedcount, stridelevels, packedbuf); GASNETE_VISOP_SIGNAL_AND_FREE(visop, 1); } break; #endif default: gasneti_fatalerror("unrecognized visop category: %i", visop->type); } lastp = &(visop->next); /* advance */ visop_removed: ; } td->progressfn_active = 0; }
extern void gasneti_vis_progressfn(void) { #if PLATFORM_COMPILER_SUN_C /* disable warnings triggered by nesting switch-inside-for */ #pragma error_messages(off, E_LOOP_NOT_ENTERED_AT_TOP) #endif GASNET_BEGIN_FUNCTION(); /* TODO: remove this lookup */ gasnete_vis_threaddata_t *td = GASNETE_VIS_MYTHREAD; gasneti_vis_op_t **lastp = &(td->active_ops); if (td->progressfn_active) return; /* prevent recursion */ td->progressfn_active = 1; for (lastp = &(td->active_ops); *lastp; ) { gasneti_vis_op_t * const visop = *lastp; #ifdef GASNETE_VIS_PROGRESSFN_EXTRA GASNETE_VIS_PROGRESSFN_EXTRA(visop, lastp) #endif switch (visop->type) { case GASNETI_VIS_CAT_PUTPC_CHAIN: { gasneti_vispc_op_t * const vispcop = (gasneti_vispc_op_t *)visop; #if GASNETE_HAVE_LC // forward ALC if it exists and the client requested it if (vispcop->lc) { if (gasnete_test(vispcop->lc GASNETI_THREAD_PASS) == GASNET_OK) { vispcop->lc = GEX_EVENT_INVALID; if (visop->eop) GASNETE_EOP_LC_FINISH((gasnete_eop_t *)(visop->eop)); else GASNETE_IOP_LC_FINISH((gasnete_iop_t *)(visop->iop)); } else break; // no ALC yet, so cannot have operation completion } #endif if (gasnete_test(visop->event GASNETI_THREAD_PASS) == GASNET_OK) { // could potentially delay visop free until ALC of this medium payload, // but given the small size it's probably synchronously complete for most conduits anyhow gasneti_assert(!vispcop->lc); gex_AM_RequestMedium1(vispcop->tm, vispcop->rank, _hidx_gasnete_vis_pcthunk_reqh, visop->addr, visop->len, GEX_EVENT_NOW, 0, (uint8_t)visop->count); GASNETE_VISOP_SIGNAL_AND_FREE(visop, 0); } break; } #ifdef GASNETE_PUTV_GATHER_SELECTOR case GASNETI_VIS_CAT_PUTV_GATHER: if (gasnete_test(visop->event GASNETI_THREAD_PASS) == GASNET_OK) { GASNETE_VISOP_SIGNAL_AND_FREE(visop, 0); } break; #endif #ifdef GASNETE_GETV_SCATTER_SELECTOR case GASNETI_VIS_CAT_GETV_SCATTER: if (gasnete_test(visop->event GASNETI_THREAD_PASS) == GASNET_OK) { gex_Memvec_t const * const savedlst = (gex_Memvec_t const *)(visop + 1); void const * const packedbuf = savedlst + visop->count; gasnete_memvec_unpack(visop->count, savedlst, packedbuf, 0, (size_t)-1); GASNETE_VISOP_SIGNAL_AND_FREE(visop, 1); } break; #endif #ifdef GASNETE_PUTI_GATHER_SELECTOR case GASNETI_VIS_CAT_PUTI_GATHER: if (gasnete_test(visop->event GASNETI_THREAD_PASS) == GASNET_OK) { GASNETE_VISOP_SIGNAL_AND_FREE(visop, 0); } break; #endif #ifdef GASNETE_GETI_SCATTER_SELECTOR case GASNETI_VIS_CAT_GETI_SCATTER: if (gasnete_test(visop->event GASNETI_THREAD_PASS) == GASNET_OK) { void * const * const savedlst = (void * const *)(visop + 1); void const * const packedbuf = savedlst + visop->count; gasnete_addrlist_unpack(visop->count, savedlst, visop->len, packedbuf, 0, (size_t)-1); GASNETE_VISOP_SIGNAL_AND_FREE(visop, 1); } break; #endif #ifdef GASNETE_PUTS_GATHER_SELECTOR case GASNETI_VIS_CAT_PUTS_GATHER: if (gasnete_test(visop->event GASNETI_THREAD_PASS) == GASNET_OK) { GASNETE_VISOP_SIGNAL_AND_FREE(visop, 0); } break; #endif #ifdef GASNETE_GETS_SCATTER_SELECTOR case GASNETI_VIS_CAT_GETS_SCATTER: if (gasnete_test(visop->event GASNETI_THREAD_PASS) == GASNET_OK) { size_t stridelevels = visop->len; size_t * const savedstrides = (size_t *)(visop + 1); size_t * const savedcount = savedstrides + stridelevels; void * const packedbuf = (void *)(savedcount + stridelevels + 1); gasnete_strided_unpack_all(visop->addr, savedstrides, savedcount, stridelevels, packedbuf); GASNETE_VISOP_SIGNAL_AND_FREE(visop, 1); } break; #endif default: gasneti_unreachable_error(("unrecognized visop category: 0x%x", (int)visop->type)); } lastp = &(visop->next); /* advance */ visop_removed: ; } td->progressfn_active = 0; #if PLATFORM_COMPILER_SUN_C /* resume default treatment of the message we suppressed */ #pragma error_messages(default, E_LOOP_NOT_ENTERED_AT_TOP) #endif }