/** * 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); }
/** * 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; }