/** * Collector creation function * @pre num >= 1 */ snet_stream_t *CollectorCreateStatic( int num, snet_stream_t **instreams, int location, snet_info_t *info) { snet_stream_t *outstream; coll_arg_t *carg; int i; assert(num >= 1); /* create outstream */ outstream = SNetStreamCreate(0); /* create collector handle */ carg = (coll_arg_t *) SNetMemAlloc( sizeof( coll_arg_t)); carg->output = outstream; carg->is_static = true; CARG_ST(carg, num) = num; /* copy instreams */ CARG_ST(carg, inputs) = SNetMemAlloc(num * sizeof(snet_stream_t *)); for(i=0; i<num; i++) { CARG_ST(carg, inputs[i]) = instreams[i]; } /* spawn collector task */ SNetThreadingSpawn( SNetEntityCreate( ENTITY_collect, location, SNetLocvecGet(info), "<collect>", CollectorTask, (void*)carg) ); return outstream; }
/* 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; }
/** * Convenience function for creating * Split, DetSplit, LocSplit or LocSplitDet, * dependent on parameters is_byloc and is_det */ snet_stream_t *CreateSplit( snet_stream_t *input, snet_info_t *info, snet_locvec_t *locvec, int location, snet_ast_t *box_a, int ltag, int utag, bool is_byloc, bool is_det ) { snet_info_t *newInfo = SNetInfoCopy(info); snet_stream_t *initial, *output; split_arg_t *sarg; snet_locvec_t *locvec; locvec = SNetLocvecGet(info); SNetLocvecSplitEnter(locvec); SNetLocvecSet(newInfo, SNetLocvecCopy(locvec)); input = SNetRouteUpdate(newInfo, input, location); if(SNetDistribIsNodeLocation(location)) { initial = SNetStreamCreate(0); sarg = (split_arg_t *) SNetMemAlloc( sizeof( split_arg_t)); sarg->input = input; sarg->output = initial; sarg->boxfun = box_a; sarg->info = newInfo; sarg->ltag = ltag; sarg->utag = utag; sarg->is_det = is_det; sarg->is_byloc = is_byloc; sarg->location = location; SNetThreadingSpawn( SNetEntityCreate( ENTITY_split, location, locvec, "<split>", SplitBoxTask, (void*)sarg) ); output = CollectorCreateDynamic( initial, location, info); } else { SNetLocvecDestroy(SNetLocvecGet(newInfo)); SNetInfoDestroy(newInfo); output = input; } SNetLocvecSplitLeave(locvec); return output; }
void SNetInInputInit(FILE *file, snetin_label_t *labels, snetin_interface_t *interfaces, snet_stream_t *in_buf ) { handle_t *hnd = SNetMemAlloc(sizeof(handle_t)); hnd->file = file; hnd->labels = labels; hnd->interfaces = interfaces; hnd->buffer = in_buf; SNetThreadingSpawn( SNetEntityCreate( ENTITY_other, -2, NULL, /* SOSI */ "glob_input", GlobInputTask, (void*)hnd) ); }
/** * Collector creation function */ snet_stream_t *CollectorCreateDynamic( snet_stream_t *instream, int location, snet_info_t *info) { snet_stream_t *outstream; coll_arg_t *carg; /* create outstream */ outstream = SNetStreamCreate(0); /* create collector handle */ carg = (coll_arg_t *) SNetMemAlloc( sizeof( coll_arg_t)); carg->output = outstream; carg->is_static = false; CARG_DYN(carg, input) = instream; /* spawn collector task */ SNetThreadingSpawn( SNetEntityCreate( ENTITY_collect, location, SNetLocvecGet(info), "<collect>", CollectorTask, (void*)carg) ); return outstream; }
/** * Box creation function */ snet_stream_t *SNetBox(snet_stream_t *input, snet_info_t *info, int location, const char *boxname, snet_box_fun_t boxfun, snet_exerealm_create_fun_t er_create, snet_exerealm_update_fun_t er_update, snet_exerealm_destroy_fun_t er_destroy, snet_int_list_list_t *output_variants) { int i,j; snet_stream_t *output; box_arg_t *barg; snet_variant_list_t *vlist; input = SNetRouteUpdate(info, input, location); if(SNetDistribIsNodeLocation(location)) { output = SNetStreamCreate(0); vlist = SNetVariantListCreate(0); for(i=0; i<SNetIntListListLength(output_variants); i++) { snet_int_list_t *l = SNetIntListListGet(output_variants, i); snet_variant_t *v = SNetVariantCreateEmpty(); for(j=0; j<SNetIntListLength(l); j+=2) { switch(SNetIntListGet(l, j)) { case field: SNetVariantAddField(v, SNetIntListGet(l, j+1)); break; case tag: SNetVariantAddTag(v, SNetIntListGet(l, j+1)); break; case btag: SNetVariantAddBTag(v, SNetIntListGet(l, j+1)); break; default: assert(0); } } SNetVariantListAppendEnd(vlist, v); } barg = (box_arg_t *) SNetMemAlloc(sizeof(box_arg_t)); barg->input = input; barg->output = output; barg->boxfun = boxfun; barg->exerealm_create = er_create; barg->exerealm_update = er_update; barg->exerealm_destroy = er_destroy; /* set out signs */ barg->hnd.sign = output_variants; /* mapping */ barg->hnd.mapping = NULL; /* set variants */ barg->hnd.vars = vlist; barg->hnd = *barg->exerealm_create(&barg->hnd); SNetThreadingSpawn( SNetEntityCreate(ENTITY_box, location, SNetLocvecGet(info), boxname, BoxTask, (void*)barg) ); } else { SNetIntListListDestroy(output_variants); output = input; } return output; }
snet_stream_t *SNetFeedbackDet( 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; snet_locvec_t *locvec; locvec = SNetLocvecGet(info); SNetLocvecFeedbackEnter(locvec); input = SNetRouteUpdate(info, input, location); if(SNetDistribIsNodeLocation(location)) { snet_stream_t *into_op, *from_op; snet_stream_t *back_bufin, *back_bufout; fbbuf_arg_t *fbbarg; fbcoll_arg_t *fbcarg; fbdisp_arg_t *fbdarg; /* create streams */ into_op = SNetStreamCreate(0); output = SNetStreamCreate(0); back_bufout = SNetStreamCreate(FEEDBACK_BACKCHAN_CAPACITY); #ifndef FEEDBACK_OMIT_BUFFER back_bufin = SNetStreamCreate(0); /* create the feedback buffer */ fbbarg = SNetMemAlloc( sizeof( fbbuf_arg_t)); fbbarg->in = back_bufin; fbbarg->out = back_bufout; fbbarg->out_capacity = FEEDBACK_BACKCHAN_CAPACITY; SNetThreadingSpawn( SNetEntityCreate( ENTITY_fbbuf, location, locvec, "<fbbuf>", FeedbackBufTask, (void*)fbbarg) ); #else back_bufin = back_bufout; #endif /* create the feedback collector */ fbcarg = SNetMemAlloc( sizeof( fbcoll_arg_t)); fbcarg->in = input; fbcarg->fbi = back_bufout; fbcarg->out = into_op; SNetThreadingSpawn( SNetEntityCreate( ENTITY_fbcoll, location, locvec, "<fbcoll>", FeedbackCollTask, (void*)fbcarg) ); /* create the instance network */ from_op = box_a(into_op, info, location); from_op = SNetRouteUpdate(info, from_op, location); /* create the feedback dispatcher */ fbdarg = SNetMemAlloc( sizeof( fbdisp_arg_t)); fbdarg->in = from_op; fbdarg->fbo = back_bufin; fbdarg->out = output; fbdarg->back_patterns = back_patterns; fbdarg->guards = guards; SNetThreadingSpawn( SNetEntityCreate( ENTITY_fbdisp, location, locvec, "<fbdisp>", FeedbackDispTask, (void*)fbdarg) ); } else { SNetVariantListDestroy(back_patterns); SNetExprListDestroy(guards); output = box_a(input, info, location); output = SNetRouteUpdate(info, output, location); } SNetLocvecFeedbackLeave(locvec); return( output); }
/* 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; }
/** * 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; }