Пример #1
0
/* Deallocate input node */
void SNetStopInput(node_t *node, fifo_t *fifo)
{
  input_arg_t   *iarg = NODE_SPEC(node, input);

  trace(__func__);
  iarg->indesc->landing->refs = 0;
  SNetFreeLanding(iarg->indesc->landing);
  SNetDelete(iarg->indesc);
  SNetStopStream(iarg->output, fifo);
  SNetDelete(node);
}
Пример #2
0
/* Destroy a stream descriptor. */
void SNetStreamClose(snet_stream_desc_t *desc)
{
  trace(__func__);
  assert(desc->refs == 0);
  SNetFifoDone(&desc->fifo);
  SNetDelete(desc);
}
Пример #3
0
/* Free a stream */
void SNetStreamDestroy(snet_stream_t *stream)
{
  trace(__func__);

  stream->from = NULL;
  stream->dest = NULL;
  SNetDelete(stream);
}
Пример #4
0
/* A record arriving via the loopback now leaves the feedback network.
 * Remove the detref structure and check for termination conditions. */
void SNetFeedbackLeave(snet_record_t *rec, landing_t *landing, fifo_t *detfifo)
{
  snet_stack_t          *stack;
  detref_t              *detref, *first;

  trace(__func__);

  // record must have a stack of detrefs
  if ((stack = DATA_REC(rec, detref)) == NULL) {
    SNetUtilDebugFatal("[%s]: missing stack.", __func__);
  }

  // stack must have at least one detref
  if ((detref = SNetStackPop(stack)) == NULL) {
    SNetUtilDebugFatal("[%s]: empty stack.", __func__);
  }
  if (SNetStackIsEmpty(stack)) {
    SNetStackDestroy(stack);
    DATA_REC(rec, detref) = NULL;
  }

  // detref must refer to this DetLeave node
  if (detref->leave != landing) {
    SNetUtilDebugFatal("[%s]: leave %p != landing %p.", __func__,
                       detref->leave, landing);
  }

  // reference counter must be at least two
  if (detref->refcount < 2) {
    SNetUtilDebugFatal("[%s]: refcnt %d < 1.", __func__, detref->refcount);
  }

  // decrease reference count
  if (DETREF_DECR(detref) == 1) {
    DETREF_DECR(detref);
  }
  assert(detref->refcount >= 0);

  // pop detrefs in sequence which have no more records in the loopback left.
  while ((first = SNetFifoPeekFirst(detfifo)) != NULL) {
    // stop processing if more records to come for this sequence counter
    if (first->refcount > 0) {
      break;
    }

    SNetFifoGet(detfifo);
    SNetFifoDone(&first->recfifo);
    SNetDelete(first);
  }
}
Пример #5
0
/* Destroy a worker. */
void SNetWorkerDestroy(worker_t *worker)
{
  trace(__func__);

  /* if (SNetVerbose()) {
    if (worker->id == 1) {
      printf("Created %u records\n", SNetGetRecCounter());
    }
  } */

  /* Verify hash table is empty. */
  if ( ! SNetHashPtrTabEmpty(worker->hash_ptab)) {
    snet_stream_desc_t *desc = SNetHashPtrFirst(worker->hash_ptab);
    do {
      work_item_t *item = SNetHashPtrLookup(worker->hash_ptab, desc);
      printf("%s(%d,%d): desc %p, count %d, refs %d\n", __func__,
             worker->id, worker->role, desc, item->count, desc->refs);
    } while ((desc = SNetHashPtrNext(worker->hash_ptab, desc)) != NULL);
  }

  /* Free hash table. */
  SNetHashPtrTabDestroy(worker->hash_ptab);

  /* Free the list of free work items. */
  while (worker->free.head) {
    work_item_t *item = worker->free.head;
    worker->free.head = item->next_free;
    SNetDelete(item);
  }

  /* Free lock */
  SNetDelete(worker->steal_lock);
  SNetDelete(worker->steal_turn);

  /* Free worker. */
  SNetDelete(worker);
}
Пример #6
0
/* Minimize the number of cached work items on the free list. */
static void ReduceWorkItems(worker_t *worker)
{
  work_item_t *item;
  while ((item = worker->free.head) != NULL &&
         (item->turn < worker->steal_turn->turn ||
          (item->turn == worker->steal_turn->turn &&
           worker->steal_lock->id == 0)))
  {
    if ((worker->free.head = item->next_free) == NULL) {
      worker->free.tail = NULL;
    }
    --worker->free.count;
    SNetDelete(item);
  }
}
Пример #7
0
/* Check if there are any records in the dripback loop left. */
static bool DripBackCheckBusy(landing_dripback2_t *db2)
{
  detref_t              *first;

  /* check if dripback loop is still active */
  while ((first = SNetFifoPeekFirst(&db2->detfifo)) != NULL) {
    BAR();
    if (first->refcount > 0) {
      break;
    }
    SNetFifoGet(&db2->detfifo);
    SNetFifoDone(&first->recfifo);
    SNetDelete(first);
  }

  return first ? true : false;
}
Пример #8
0
/* Destroy a star node. */
void SNetStopStar(node_t *node, fifo_t *fifo)
{
  star_arg_t *sarg = NODE_SPEC(node, star);
  trace(__func__);
  if (!sarg->stopping) {
    sarg->stopping = 1;
    SNetStopStream(sarg->instance, fifo);
  }
  else if (sarg->stopping == 1) {
    sarg->stopping = 2;
    SNetStopStream(sarg->collector, fifo);
    SNetExprListDestroy(sarg->guards);
    SNetVariantListDestroy(sarg->exit_patterns);
    SNetEntityDestroy(sarg->entity);
    SNetDelete(node);
  }
}
Пример #9
0
/* Destroy a dripback node. */
void SNetStopDripBack(node_t *node, fifo_t *fifo)
{
  dripback_arg_t *darg = NODE_SPEC(node, dripback);
  trace(__func__);
  if (darg->stopping == 0) {
    darg->stopping = 1;
    SNetStopStream(darg->instance, fifo);
  }
  else if (darg->stopping == 1) {
    darg->stopping = 2;
    SNetStopStream(darg->output, fifo);
    SNetVariantListDestroy(darg->back_patterns);
    SNetExprListDestroy(darg->guards);
    SNetStreamDestroy(darg->selfref);
    SNetEntityDestroy(darg->entity);
    SNetDelete(node);
  }
}
Пример #10
0
/* Check if there are any records in the feedback loop left. */
static void FeedbackCheckBusy(landing_feedback3_t *fb3)
{
  detref_t              *first;

  /* check if feedback loop is still active */
  while ((first = SNetFifoPeekFirst(&fb3->detfifo)) != NULL) {
    if (first->refcount > 0) {
      break;
    }
    SNetFifoGet(&fb3->detfifo);
    SNetFifoDone(&first->recfifo);
    SNetDelete(first);
  }

  if (first == NULL && fb3->terminate == FeedbackDraining) {
    fb3->terminate = FeedbackTerminating;
  }
}
Пример #11
0
/**
 * Convenience function for creating
 * Star, DetStar, StarIncarnate or DetStarIncarnate,
 * dependent on parameters is_incarnate and is_det.
 */
static snet_stream_t *CreateStar(
    snet_stream_t       *input,
    snet_info_t         *info,
    int                  location,
    snet_variant_list_t *exit_patterns,
    snet_expr_list_t    *guards,
    snet_startup_fun_t   box_a,
    snet_startup_fun_t   box_b,
    bool                 is_incarnate,
    bool                 is_det)
{
  snet_stream_t *output;
  node_t        *node;
  star_arg_t    *sarg;
  snet_locvec_t *locvec;

  locvec = SNetLocvecGet(info);
  if (!is_incarnate) {
    SNetLocvecStarEnter(locvec);
  } else {
    assert(false);
  }

  output = SNetStreamCreate(0);
  node = SNetNodeNew(NODE_star, location, &input, 1, &output, 1,
                     SNetNodeStar, SNetStopStar, SNetTermStar);
  sarg = NODE_SPEC(node, star);
  sarg->input = input;
  sarg->collector = output;
  sarg->exit_patterns = exit_patterns;
  sarg->guards = guards;
  sarg->is_incarnate = is_incarnate;
  sarg->is_det = is_det;
  sarg->is_detsup = (SNetDetGetLevel() > 0);
  sarg->stopping = 0;

  /* create operand A */
  sarg->instance = SNetNodeStreamCreate(node);
  (void) SNetLocvecStarSpawn(locvec);
  SNetSubnetIncrLevel();
  sarg->internal = (*box_a)(sarg->instance, info, location);
  SNetSubnetDecrLevel();
  (void) SNetLocvecStarSpawnRet(locvec);
  /* direct destination of operand back to this node */
  STREAM_DEST(sarg->internal) = node;

  /* Is this a Star followed by only a Sync? */
  if (SNetZipperEnabled() &&
      NODE_TYPE(STREAM_DEST(sarg->instance)) == NODE_sync &&
      STREAM_FROM(sarg->internal) == STREAM_DEST(sarg->instance))
  {
    /* Replace the combination of star + sync with a fused sync-star. */
    sync_arg_t *sync = NODE_SPEC(STREAM_DEST(sarg->instance), sync);
    /* if (SNetVerbose()) {
      printf("Replacing a star + sync with a fused sync-star.\n");
    } */
    output = SNetZipper(input, info, location, exit_patterns, guards,
                        sync->patterns, sync->guard_exprs);
    SNetEntityDestroy(sync->entity);
    SNetVariantDestroy(sync->merged_pattern);
    SNetDelete(STREAM_DEST(sarg->instance));
    SNetStreamDestroy(sarg->instance);
    SNetStreamDestroy(sarg->internal);
    SNetStreamDestroy(sarg->collector);
    SNetMemFree(node);
  } else {
    sarg->entity = SNetEntityCreate( ENTITY_star, location, locvec,
                                     "<star>", NULL, (void *) sarg);
    if (!is_incarnate) {
      /* the "top-level" star also creates a collector */
      output = SNetCollectorDynamic(sarg->collector, location, info,
                                    is_det, node);
      SNetNodeTableAdd(sarg->internal);
    }
  }

  if (!is_incarnate) {
    SNetLocvecStarLeave(locvec);
  }

  return output;
}