Exemple #1
0
/* DripBack creation function */
snet_stream_t *SNetDripBack(
    snet_stream_t       *input,
    snet_info_t         *info,
    int                  location,
    snet_variant_list_t *back_patterns,
    snet_expr_list_t    *guards,
    snet_startup_fun_t   box_a)
{
  snet_stream_t  *output;
  node_t         *node;
  dripback_arg_t *darg;
  snet_locvec_t  *locvec;
  int             detlevel;

  trace(__func__);

  detlevel = SNetDetSwapLevel(0);
  locvec = SNetLocvecGet(info);
  SNetLocvecFeedbackEnter(locvec);

  output = SNetStreamCreate(0);
  node = SNetNodeNew(NODE_dripback, location, &input, 1, &output, 1,
                     SNetNodeDripBack, SNetStopDripBack, SNetTermDripBack);
  darg = NODE_SPEC(node, dripback);

  /* fill in the node argument */
  darg->input = input;
  darg->output = output;
  darg->back_patterns = back_patterns;
  darg->guards = guards;
  darg->stopping = 0;

  /* Create the instance network */
  darg->instance = SNetNodeStreamCreate(node);
  SNetSubnetIncrLevel();
  darg->dripback = (*box_a)(darg->instance, info, location);
  SNetSubnetDecrLevel();
  STREAM_DEST(darg->dripback) = node;
  SNetNodeTableAdd(darg->dripback);

  /* Create one self-referencing stream. */
  darg->selfref = SNetNodeStreamCreate(node);
  STREAM_DEST(darg->selfref) = node;
  SNetNodeTableAdd(darg->selfref);

  darg->entity = SNetEntityCreate( ENTITY_fbdisp, location, locvec,
                                   "<feedback>", NULL, (void*)darg);

  SNetLocvecFeedbackLeave(locvec);
  SNetDetSwapLevel(detlevel);

  return output;
}
Exemple #2
0
/* Allocate a new stream */
snet_stream_t *SNetStreamCreate(int capacity)
{
  snet_stream_t *stream;

  trace(__func__);
  stream = SNetNewAlign(snet_stream_t);
  STREAM_FROM(stream) = NULL;
  STREAM_DEST(stream) = NULL;

  return stream;
}
Exemple #3
0
/* Open a descriptor to an output stream.
 *
 * The source landing which opens the stream is determined by parameter 'prev'.
 * The new descriptor holds a pointer to a landing which instantiates
 * the destination node as determined by the stream parameter 'stream'.
 *
 * Special cases:
 * (1) Dispatchers should create an additional landing for a future collector
 * and push this landing onto a stack of future landings.
 * (2) Collectors should retrieve their designated landing from this stack
 * and verify that it is theirs.
 */
snet_stream_desc_t *SNetStreamOpen(
    snet_stream_t *stream,
    snet_stream_desc_t *prev)
{
  snet_stream_desc_t    *desc;

  trace(__func__);

  desc = SNetNewAlign(snet_stream_desc_t);
  DESC_STREAM(desc) = stream;
  desc->source = prev->landing;
  desc->refs = 1;
  SNetFifoInit(&desc->fifo);

  switch (NODE_TYPE(stream->dest)) {

    case NODE_filter:
    case NODE_nameshift:
    case NODE_output:
      desc->landing = SNetNewLanding(DESC_DEST(desc), prev, LAND_siso);
      DESC_LAND_SPEC(desc, siso)->outdesc = NULL;
      break;

    case NODE_box:
      SNetNewBoxLanding(desc, prev);
      break;

    case NODE_parallel:
      SNetNewParallelLanding(desc, prev);
      break;

    case NODE_star:
      SNetNewStarLanding(desc, prev);
      break;

    case NODE_split:
      SNetNewSplitLanding(desc, prev);
      break;

    case NODE_feedback:
      SNetNewFeedbackLanding(desc, prev);
      break;

    case NODE_dripback:
      SNetNewDripBackLanding(desc, prev);
      break;

    case NODE_sync:
      desc->landing = SNetNewLanding(STREAM_DEST(stream), prev, LAND_sync);
      SNetSyncInitDesc(desc, stream);
      break;

    case NODE_zipper:
      /* Init the landing state of a fused sync-star node */
      desc->landing = SNetNewLanding(STREAM_DEST(stream), prev, LAND_zipper);
      DESC_LAND_SPEC(desc, zipper)->outdesc = NULL;
      DESC_LAND_SPEC(desc, zipper)->head = NULL;
      break;

    case NODE_collector:
      /* Collectors receive the previously created landing from the stack */
      desc->landing = SNetPopLanding(prev);
      assert(desc->landing);
      assert(desc->landing->type == LAND_collector);
      assert(DESC_NODE(desc) == STREAM_DEST(stream));
      assert(desc->landing->refs > 0);
      break;

    case NODE_observer:
      desc->landing = SNetNewLanding(DESC_DEST(desc), prev, LAND_observer);
      DESC_LAND_SPEC(desc, observer)->outdesc = NULL;
      DESC_LAND_SPEC(desc, observer)->oid = 0;
      break;

    case NODE_observer2:
      desc->landing = SNetPopLanding(prev);
      assert(desc->landing);
      assert(desc->landing->type == LAND_empty);
      break;

    case NODE_input:
    case NODE_identity:
    case NODE_garbage:
    default:
      desc->landing = NULL;
      assert(0);
      break;
  }

  /* if (SNetVerbose() && SNetNodeGetWorkerCount() <= 1) {
    printf("%s: %s, %s\n", __func__,
           SNetNodeName(desc->landing->node), SNetLandingName(desc->landing));
  } */

  return desc;
}
Exemple #4
0
/* Deallocate a stream, but remember it's destination node. */
void SNetStopStream(snet_stream_t *stream, fifo_t *fifo)
{
  SNetFifoPut(fifo, STREAM_DEST(stream));
  SNetStreamDestroy(stream);
}
Exemple #5
0
/* Feedback creation function */
snet_stream_t *SNetFeedback(
    snet_stream_t       *input,
    snet_info_t         *info,
    int                  location,
    snet_variant_list_t *back_patterns,
    snet_expr_list_t    *guards,
    snet_startup_fun_t   box_a)
{
  snet_stream_t  *output;
  node_t         *node;
  feedback_arg_t *farg;
  snet_locvec_t  *locvec;
  int             detlevel;

  trace(__func__);
  if (SNetFeedbackDeterministic()) {
    return SNetDripBack(input, info, location, back_patterns, guards, box_a);
  }
  detlevel = SNetDetSwapLevel(0);
  locvec = SNetLocvecGet(info);
  SNetLocvecFeedbackEnter(locvec);
  input = SNetRouteUpdate(info, input, location);

  if (SNetDistribIsNodeLocation(location)) {
    output = SNetStreamCreate(0);
    node = SNetNodeNew(NODE_feedback, &input, 1, &output, 1,
                       SNetNodeFeedback, SNetStopFeedback, SNetTermFeedback);
    farg = NODE_SPEC(node, feedback);

    /* fill in the node argument */
    farg->input = input;
    farg->output = output;
    farg->back_patterns = back_patterns;
    farg->guards = guards;
    farg->stopping = 0;

    /* Create the instance network */
    farg->instance = SNetNodeStreamCreate(node);
    farg->feedback = (*box_a)(farg->instance, info, location);
    farg->feedback = SNetRouteUpdate(info, farg->feedback, location);

    /* Feedback loop should end at this node. */
    assert(STREAM_DEST(farg->feedback) == NULL);
    STREAM_DEST(farg->feedback) = node;

    /* Create two self-referencing streams. */
    farg->selfref2 = SNetNodeStreamCreate(node);
    STREAM_DEST(farg->selfref2) = node;
    farg->selfref4 = SNetNodeStreamCreate(node);
    STREAM_DEST(farg->selfref4) = node;

    farg->entity = SNetEntityCreate( ENTITY_fbdisp, location, locvec,
                                     "<feedback>", NULL, (void*)farg);
  } else {
    SNetExprListDestroy( guards);
    SNetVariantListDestroy(back_patterns);
    output = input;
  }

  SNetLocvecFeedbackLeave(locvec);
  SNetDetSwapLevel(detlevel);

  return output;
}
Exemple #6
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;
}