Пример #1
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
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;
}
Пример #3
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;
}
Пример #4
0
airThreadBarrier *
airThreadBarrierNew(unsigned int numUsers) {
  airThreadBarrier *barrier;
  
  barrier = (airThreadBarrier *)calloc(1, sizeof(airThreadBarrier));
  if (barrier) {
    barrier->numUsers = numUsers;
    barrier->numDone = 0;
    if (!(barrier->doneMutex = airThreadMutexNew())) {
      airFree(barrier);
      return NULL;
    }
    if (!(barrier->doneCond = airThreadCondNew())) {
      barrier->doneMutex = airThreadMutexNix(barrier->doneMutex);
      airFree(barrier);
      return NULL;
    }
  }
  return barrier;
}
Пример #5
0
/*
******** 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;
}
Пример #6
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;
}