예제 #1
0
int
coilFinish(coilContext *cctx) {
  char me[]="coilFinish", err[BIFF_STRLEN];
  unsigned int tidx;

  if (!cctx) {
    sprintf(err, "%s: got NULL pointer", me);
    biffAdd(COIL, err); return 1;
  }

  if (cctx->verbose > 1) {
    fprintf(stderr, "%s: finishing workers\n", me);
  }
  cctx->finished = AIR_TRUE;
  if (cctx->numThreads > 1) {
    airThreadBarrierWait(cctx->filterBarrier);
    for (tidx=1; tidx<cctx->numThreads; tidx++) {
      airThreadJoin(cctx->task[tidx]->thread, &(cctx->task[tidx]->returnPtr));
      cctx->task[tidx]->thread = airThreadNix(cctx->task[tidx]->thread);
      cctx->task[tidx] = _coilTaskNix(cctx->task[tidx]);
    }
  }
  cctx->task[0]->thread = airThreadNix(cctx->task[0]->thread);
  cctx->task[0] = _coilTaskNix(cctx->task[0]);
  cctx->task = (coilTask **)airFree(cctx->task);

  if (cctx->numThreads > 1) {
    cctx->nextSliceMutex = airThreadMutexNix(cctx->nextSliceMutex);
    cctx->filterBarrier = airThreadBarrierNix(cctx->filterBarrier);
    cctx->updateBarrier = airThreadBarrierNix(cctx->updateBarrier);
  }

  return 0;
}
예제 #2
0
airThreadBarrier *
airThreadBarrierNix(airThreadBarrier *barrier) {
  
  barrier->doneMutex = airThreadMutexNix(barrier->doneMutex);
  barrier->doneCond = airThreadCondNix(barrier->doneCond);
  airFree(barrier);
  return NULL;
}
예제 #3
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;
}
/*
** this is called *after* pushOutputGet
**
** should nix everything created by the many _push*Setup() functions
*/
int
pushFinish(pushContext *pctx) {
  char me[]="pushFinish", err[BIFF_STRLEN];
  unsigned int ii, tidx;

  if (!pctx) {
    sprintf(err, "%s: got NULL pointer", me);
    biffAdd(PUSH, err); return 1;
  }

  if (pctx->verbose > 1) {
    fprintf(stderr, "%s: finishing workers\n", me);
  }
  pctx->finished = AIR_TRUE;
  if (pctx->numThread > 1) {
    airThreadBarrierWait(pctx->stageBarrierA);
  }
  for (tidx=pctx->numThread; tidx>0; tidx--) {
    if (tidx-1) {
      airThreadJoin(pctx->task[tidx-1]->thread,
                    &(pctx->task[tidx-1]->returnPtr));
    }
    pctx->task[tidx-1]->thread = airThreadNix(pctx->task[tidx-1]->thread);
    pctx->task[tidx-1] = _pushTaskNix(pctx->task[tidx-1]);
  }
  pctx->task = (pushTask **)airFree(pctx->task);

  pctx->nten = nrrdNuke(pctx->nten);
  pctx->ninv = nrrdNuke(pctx->ninv);
  pctx->nmask = nrrdNuke(pctx->nmask);
  pctx->gctx = gageContextNix(pctx->gctx);
  pctx->fctx = tenFiberContextNix(pctx->fctx);
  for (ii=0; ii<pctx->numBin; ii++) {
    pushBinDone(pctx->bin + ii);
  }
  pctx->bin = (pushBin *)airFree(pctx->bin);
  pctx->binsEdge = pctx->numBin = 0;

  if (pctx->numThread > 1) {
    pctx->binMutex = airThreadMutexNix(pctx->binMutex);
    pctx->stageBarrierA = airThreadBarrierNix(pctx->stageBarrierA);
    pctx->stageBarrierB = airThreadBarrierNix(pctx->stageBarrierB);
  }

  return 0;
}
예제 #5
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;
}
예제 #6
0
/*
** this is called *after* pullOutputGet
**
** should nix everything created by the many _pull*Setup() functions
*/
int
pullFinish(pullContext *pctx) {
  char me[]="pullFinish", err[BIFF_STRLEN];
  unsigned int tidx;

  if (!pctx) {
    sprintf(err, "%s: got NULL pointer", me);
    biffAdd(PULL, err); return 1;
  }

  pctx->finished = AIR_TRUE;
  if (pctx->threadNum > 1) {
    if (pctx->verbose > 1) {
      fprintf(stderr, "%s: finishing workers\n", me);
    }
    airThreadBarrierWait(pctx->iterBarrierA);
    /* worker threads now pass barrierA and see that finished is AIR_TRUE,
       and then bail, so now we collect them */
    for (tidx=pctx->threadNum; tidx>0; tidx--) {
      if (tidx-1) {
        airThreadJoin(pctx->task[tidx-1]->thread,
                      &(pctx->task[tidx-1]->returnPtr));
      }
    }
    pctx->binMutex = airThreadMutexNix(pctx->binMutex);
    pctx->iterBarrierA = airThreadBarrierNix(pctx->iterBarrierA);
    pctx->iterBarrierB = airThreadBarrierNix(pctx->iterBarrierB);
  }

  /* no need for _pullVolumeFinish(pctx), at least not now */
  /* no need for _pullInfoFinish(pctx), at least not now */
  _pullTaskFinish(pctx);
  _pullBinFinish(pctx);
  _pullPointFinish(pctx); /* yes, nixed bins deleted pnts inside, but
                             other buffers still have to be freed */

  return 0;
}
예제 #7
0
파일: rays.c 프로젝트: ryanfb/teem-parallel
/*
******** 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;
}