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