coilTask * _coilTaskNew(coilContext *cctx, int threadIdx) { coilTask *task; int len, diam, xi; len = cctx->kind->valLen; diam = 1 + 2*cctx->radius; task = (coilTask *)calloc(1, sizeof(coilTask)); if (task) { task->cctx = cctx; task->thread = airThreadNew(); task->threadIdx = threadIdx; task->_iv3 = (coil_t*)calloc(len*diam*diam*diam, sizeof(coil_t)); task->iv3 = (coil_t**)calloc(diam, sizeof(coil_t*)); for (xi=0; xi<diam; xi++) { task->iv3[xi] = task->_iv3 + xi*len*diam*diam; } if (1 == cctx->radius && 1 == cctx->kind->valLen) { task->iv3Fill = _coilIv3Fill_1_1; } else if (1 == cctx->radius && 7 == cctx->kind->valLen) { task->iv3Fill = _coilIv3Fill_1_7; } else { task->iv3Fill = _coilIv3Fill_R_L; } task->returnPtr = NULL; } return task; }
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; }
echoThreadState * echoThreadStateNew(void) { echoThreadState *state; state = (echoThreadState *)calloc(1, sizeof(echoThreadState)); if (state) { state->thread = airThreadNew(); state->verbose = 0; state->threadIdx = -1; state->depth = -1; state->njitt = nrrdNew(); state->nperm = nrrdNew(); state->permBuff = NULL; state->jitt = NULL; state->chanBuff = NULL; state->rst = airRandMTStateNew(0); state->returnPtr = NULL; } return state; }
/* ******** hooverRender() ** ** because of the biff usage(), only one thread can call hooverRender(), ** and no promises if the threads themselves call biff... */ int hooverRender(hooverContext *ctx, int *errCodeP, int *errThreadP) { char me[]="hooverRender", err[BIFF_STRLEN]; _hooverExtraContext *ec; _hooverThreadArg args[HOOVER_THREAD_MAX]; _hooverThreadArg *errArg; airThread *thread[HOOVER_THREAD_MAX]; _htpu u; void *render; int ret; airArray *mop; int threadIdx; if (!( errCodeP && errThreadP )) { sprintf(err, "%s: got NULL int return pointer", me); biffAdd(HOOVER, err); return hooverErrInit; } /* this calls limnCameraUpdate() */ if (hooverContextCheck(ctx)) { sprintf(err, "%s: problem detected in given context", me); biffAdd(HOOVER, err); *errCodeP = 0; *errThreadP = 0; return hooverErrInit; } if (!(ec = _hooverExtraContextNew(ctx))) { sprintf(err, "%s: problem creating thread context", me); biffAdd(HOOVER, err); *errCodeP = 0; *errThreadP = 0; return hooverErrInit; } mop = airMopNew(); airMopAdd(mop, ec, (airMopper)_hooverExtraContextNix, airMopAlways); if ( (ret = (ctx->renderBegin)(&render, ctx->user)) ) { *errCodeP = ret; *errCodeP = 0; *errThreadP = 0; airMopError(mop); return hooverErrRenderBegin; } for (threadIdx=0; threadIdx<ctx->numThreads; threadIdx++) { args[threadIdx].ctx = ctx; args[threadIdx].ec = ec; args[threadIdx].render = render; args[threadIdx].whichThread = threadIdx; args[threadIdx].whichErr = hooverErrNone; args[threadIdx].errCode = 0; thread[threadIdx] = airThreadNew(); } ctx->workIdx = 0; if (1 < ctx->numThreads) { ctx->workMutex = airThreadMutexNew(); } else { ctx->workMutex = NULL; } /* (done): call airThreadStart() once per thread, passing the address of a distinct (and appropriately intialized) _hooverThreadArg to each. If return of airThreadStart() is non-zero, put its return in *errCodeP, the number of the problematic in *errThreadP, and return hooverErrThreadCreate. Then call airThreadJoin() on all the threads, passing &errArg as "retval". On non-zero return, set *errCodeP and *errThreadP, and return hooverErrThreadJoin. If return of airThreadJoin() is zero, but the errArg is non-NULL, then assume that this errArg is actually just the passed _hooverThreadArg returned to us, and from this copy errArg->errCode into *errCodeP, and return errArg->whichErr */ if (1 < ctx->numThreads && !airThreadCapable) { fprintf(stderr, "%s: WARNING: not multi-threaded; will do %d " "\"threads\" serially !!!\n", me, ctx->numThreads); } for (threadIdx=0; threadIdx<ctx->numThreads; threadIdx++) { if ((ret = airThreadStart(thread[threadIdx], _hooverThreadBody, (void *) &args[threadIdx]))) { *errCodeP = ret; *errThreadP = threadIdx; airMopError(mop); return hooverErrThreadCreate; } } for (threadIdx=0; threadIdx<ctx->numThreads; threadIdx++) { u.h = &errArg; if ((ret = airThreadJoin(thread[threadIdx], u.v))) { *errCodeP = ret; *errThreadP = threadIdx; airMopError(mop); return hooverErrThreadJoin; } if (errArg != NULL) { *errCodeP = errArg->errCode; *errThreadP = threadIdx; return errArg->whichErr; } thread[threadIdx] = airThreadNix(thread[threadIdx]); } if (1 < ctx->numThreads) { ctx->workMutex = airThreadMutexNix(ctx->workMutex); } if ( (ret = (ctx->renderEnd)(render, ctx->user)) ) { *errCodeP = ret; *errThreadP = -1; return hooverErrRenderEnd; } render = NULL; airMopOkay(mop); *errCodeP = 0; *errThreadP = 0; return hooverErrNone; }
pullTask * _pullTaskNew(pullContext *pctx, int threadIdx) { char me[]="_pullTaskNew", err[BIFF_STRLEN]; pullTask *task; unsigned int ii, offset; task = (pullTask *)calloc(1, sizeof(pullTask)); if (!task) { sprintf(err, "%s: couldn't allocate task", me); biffAdd(PULL, err); return NULL; } task->pctx = pctx; for (ii=0; ii<pctx->volNum; ii++) { if (!(task->vol[ii] = _pullVolumeCopy(pctx->vol[ii]))) { sprintf(err, "%s: trouble copying vol %u/%u", me, ii, pctx->volNum); biffAdd(PULL, err); return NULL; } } if (0) { gagePerVolume *pvl; const double *ans; double pos[3]; int gret; for (ii=0; ii<pctx->volNum; ii++) { pvl = task->vol[ii]->gctx->pvl[0]; fprintf(stderr, "!%s: vol[%u] query:\n", me, ii); gageQueryPrint(stderr, pvl->kind, pvl->query); ans = gageAnswerPointer(task->vol[ii]->gctx, pvl, gageSclValue); ELL_3V_SET(pos, 0.6, 0.6, 0.3); gret = gageProbeSpace(task->vol[ii]->gctx, pos[0], pos[1], pos[2], AIR_FALSE, AIR_TRUE); fprintf(stderr, "!%s: (%d) val(%g,%g,%g) = %g\n", me, gret, pos[0], pos[1], pos[2], *ans); ELL_3V_SET(pos, 0.5, 0.0, 0.0); gret = gageProbeSpace(task->vol[ii]->gctx, pos[0], pos[1], pos[2], AIR_FALSE, AIR_TRUE); fprintf(stderr, "!%s: (%d) val(%g,%g,%g) = %g\n", me, gret, pos[0], pos[1], pos[2], *ans); } } offset = 0; for (ii=0; ii<=PULL_INFO_MAX; ii++) { unsigned int volIdx; if (pctx->ispec[ii]) { volIdx = pctx->ispec[ii]->volIdx; task->ans[ii] = gageAnswerPointer(task->vol[volIdx]->gctx, task->vol[volIdx]->gpvl, pctx->ispec[ii]->item); fprintf(stderr, "!%s: task->ans[%u] = %p\n", me, ii, task->ans[ii]); } else { task->ans[ii] = NULL; } } if (pctx->threadNum > 1) { task->thread = airThreadNew(); } task->threadIdx = threadIdx; task->rng = airRandMTStateNew(pctx->rngSeed + threadIdx); task->pointBuffer = pullPointNew(pctx); pctx->idtagNext = 0; /* because pullPointNew incremented it */ task->neighPoint = AIR_CAST(pullPoint **, calloc(_PULL_NEIGH_MAXNUM, sizeof(pullPoint*))); task->returnPtr = NULL; task->stuckNum = 0; return task; }