int pushStart(pushContext *pctx) { char me[]="pushStart", err[BIFF_STRLEN]; unsigned int tidx; if (_pushContextCheck(pctx)) { sprintf(err, "%s: trouble", me); biffAdd(PUSH, err); return 1; } airSrandMT(pctx->seed); /* the ordering of things below is important: gage and fiber contexts have to be set up before they're copied by task setup */ if (_pushTensorFieldSetup(pctx) || _pushGageSetup(pctx) || _pushFiberSetup(pctx) || _pushTaskSetup(pctx) || _pushBinSetup(pctx) || _pushThingSetup(pctx)) { sprintf(err, "%s: trouble setting up context", me); biffAdd(PUSH, err); return 1; } /* HEY: this should be done by the user */ pctx->process[0] = _pushForce; pctx->process[1] = _pushUpdate; pctx->finished = AIR_FALSE; if (pctx->numThread > 1) { pctx->binMutex = airThreadMutexNew(); pctx->stageBarrierA = airThreadBarrierNew(pctx->numThread); pctx->stageBarrierB = airThreadBarrierNew(pctx->numThread); } /* start threads 1 and up running; they'll all hit stageBarrierA */ for (tidx=1; tidx<pctx->numThread; tidx++) { if (pctx->verbose > 1) { fprintf(stderr, "%s: spawning thread %d\n", me, tidx); } airThreadStart(pctx->task[tidx]->thread, _pushWorker, (void *)(pctx->task[tidx])); } return 0; }
int pullStart(pullContext *pctx) { char me[]="pullStart", err[BIFF_STRLEN]; unsigned int tidx; fprintf(stderr, "!%s: hello %p\n", me, pctx); pctx->iter = 0; /* have to initialize this here because of seedOnly hack */ /* the ordering of steps below is important! e.g. gage context has to be set up (_pullVolumeSetup) by before its copied (_pullTaskSetup) */ if (_pullContextCheck(pctx) || _pullVolumeSetup(pctx) || _pullInfoSetup(pctx) || _pullTaskSetup(pctx) || _pullBinSetup(pctx) || _pullPointSetup(pctx)) { sprintf(err, "%s: trouble setting up context", me); biffAdd(PULL, err); return 1; } fprintf(stderr, "!%s: setup done-ish\n", me); if (pctx->threadNum > 1) { pctx->binMutex = airThreadMutexNew(); pctx->iterBarrierA = airThreadBarrierNew(pctx->threadNum); pctx->iterBarrierB = airThreadBarrierNew(pctx->threadNum); /* start threads 1 and up running; they'll all hit iterBarrierA */ for (tidx=1; tidx<pctx->threadNum; tidx++) { if (pctx->verbose > 1) { fprintf(stderr, "%s: spawning thread %d\n", me, tidx); } airThreadStart(pctx->task[tidx]->thread, _pullWorker, (void *)(pctx->task[tidx])); } } else { pctx->binMutex = NULL; pctx->iterBarrierA = NULL; pctx->iterBarrierB = NULL; } pctx->timeIteration = 0; pctx->timeRun = 0; return 0; }
int alanRun(alanContext *actx) { char me[]="alanRun", err[BIFF_STRLEN]; int tid, hack=AIR_FALSE; alanTask task[ALAN_THREAD_MAX]; if (_alanCheck(actx)) { sprintf(err, "%s: ", me); biffAdd(ALAN, err); return 1; } if (!( actx->_nlev[0] && actx->_nlev[0] )) { sprintf(err, "%s: _nlev[0,1] not allocated: " "call alanUpdate + alanInit", me); biffAdd(ALAN, err); return 1; } if (!airThreadCapable && 1 == actx->numThreads) { hack = airThreadNoopWarning; airThreadNoopWarning = AIR_FALSE; } actx->changeMutex = airThreadMutexNew(); actx->iterBarrier = airThreadBarrierNew(actx->numThreads); actx->averageChange = 0; actx->changeCount = 0; actx->stop = alanStopNot; for (tid=0; tid<actx->numThreads; tid++) { task[tid].actx = actx; task[tid].idx = tid; task[tid].thread = airThreadNew(); airThreadStart(task[tid].thread, _alanTuringWorker, (void *)&(task[tid])); } for (tid=0; tid<actx->numThreads; tid++) { airThreadJoin(task[tid].thread, &(task[tid].me)); task[tid].thread = airThreadNix(task[tid].thread); } actx->iterBarrier = airThreadBarrierNix(actx->iterBarrier); actx->changeMutex = airThreadMutexNix(actx->changeMutex); if (!airThreadCapable && 1 == actx->numThreads) { airThreadNoopWarning = hack; } /* we assume that someone set actx->stop */ return 0; }
int coilStart(coilContext *cctx) { char me[]="coilStart", err[BIFF_STRLEN]; int valIdx, valLen; coil_t (*lup)(const void*, size_t), *val; unsigned tidx, elIdx; if (!cctx) { sprintf(err, "%s: got NULL pointer", me); biffAdd(COIL, err); return 1; } cctx->task = (coilTask **)calloc(cctx->numThreads, sizeof(coilTask *)); if (!(cctx->task)) { sprintf(err, "%s: couldn't allocate array of tasks", me); biffAdd(COIL, err); return 1; } /* we create tasks for ALL threads, including me, thread 0 */ cctx->task[0] = NULL; for (tidx=0; tidx<cctx->numThreads; tidx++) { cctx->task[tidx] = _coilTaskNew(cctx, tidx); if (!(cctx->task[tidx])) { sprintf(err, "%s: couldn't allocate task %d", me, tidx); biffAdd(COIL, err); return 1; } } cctx->finished = AIR_FALSE; if (cctx->numThreads > 1) { cctx->nextSliceMutex = airThreadMutexNew(); cctx->filterBarrier = airThreadBarrierNew(cctx->numThreads); cctx->updateBarrier = airThreadBarrierNew(cctx->numThreads); } /* initialize the values in cctx->nvol */ val = (coil_t*)(cctx->nvol->data); valLen = cctx->kind->valLen; #if COIL_TYPE_FLOAT lup = nrrdFLookup[cctx->nin->type]; #else lup = nrrdDLookup[cctx->nin->type]; #endif for (elIdx=0; elIdx<cctx->size[0]*cctx->size[1]*cctx->size[2]; elIdx++) { for (valIdx=0; valIdx<valLen; valIdx++) { val[valIdx + 0*valLen] = lup(cctx->nin->data, valIdx + valLen*elIdx); val[valIdx + 1*valLen] = 0; } val += 2*valLen; } /* start threads 1 and up running; they'll all hit filterBarrier */ if (cctx->numThreads > 1) { for (tidx=1; tidx<cctx->numThreads; tidx++) { if (cctx->verbose > 1) { fprintf(stderr, "%s: spawning thread %d\n", me, tidx); } airThreadStart(cctx->task[tidx]->thread, _coilWorker, (void *)(cctx->task[tidx])); } } /* set things as though we've just finished an update phase */ cctx->nextSlice = cctx->size[2]; cctx->todoFilter = AIR_TRUE; cctx->todoUpdate = AIR_FALSE; return 0; }