예제 #1
0
파일: star.c 프로젝트: jsyk/snet-rts
/**
 * 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;
  star_arg_t *sarg;
  snet_stream_t *newstream;
  snet_locvec_t *locvec;

  locvec = SNetLocvecGet(info);
  if (!is_incarnate) {
    SNetLocvecStarEnter(locvec);
    input = SNetRouteUpdate(info, input, location);
  } else {
    input = SNetRouteUpdate(info, input, location);
  }

  if(SNetDistribIsNodeLocation(location)) {
    /* create the task argument */
    sarg = SNetMemAlloc( sizeof(star_arg_t));
    newstream = SNetStreamCreate(0);
    sarg->instream = SNetStreamOpen(input, 'r');
    sarg->outstream = SNetStreamOpen(newstream, 'w');
    sarg->nextstream = NULL;
    sarg->box = box_a;
    sarg->selffun = box_b;
    sarg->exit_patterns = exit_patterns;
    sarg->guards = guards;
    sarg->info = SNetInfoCopy(info);
    SNetLocvecSet(sarg->info, SNetLocvecCopy(locvec));
    sarg->is_incarnate = is_incarnate;
    sarg->is_det = is_det;
    sarg->location = location;
    sarg->sync_cleanup = false;
    sarg->counter = 0;

    SNetThreadingSpawn( ENTITY_star, location, locvec,
          "<star>", &StarBoxTask, sarg);

    /* creation function of top level star will return output stream
     * of its collector, the incarnates return their outstream
     */
    if (!is_incarnate) {
      /* the "top-level" star also creates a collector */
      output = CollectorCreateDynamic(newstream, location, info);
    } else {
      output = newstream;
    }

  } else {
    SNetExprListDestroy( guards);
    SNetVariantListDestroy(exit_patterns);
    output = input;
  }

  if (!is_incarnate) SNetLocvecStarLeave(SNetLocvecGet(info));

  return( output);
}
예제 #2
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;
}