void SNetHndDestroy( snet_handle_t *hnd) { int i; if( hnd->mapping != NULL) { for( i=0; i<hnd->mapping->num; i++) { SNetMemFree( hnd->mapping->string_names[i]); } SNetMemFree( hnd->mapping->string_names); SNetMemFree( hnd->mapping->int_names); } SNetVariantListDestroy( hnd->vars); }
static void TerminateStarBoxTask(snet_stream_desc_t *outstream, star_arg_t *sarg) { /* close streams */ SNetStreamClose( outstream, false); /* destroy the task argument */ SNetExprListDestroy( sarg->guards); SNetLocvecDestroy(SNetLocvecGet(sarg->info)); SNetInfoDestroy(sarg->info); SNetVariantListDestroy( sarg->exit_patterns); SNetMemFree( sarg); }
/* Destroy a star node. */ void SNetStopStar(node_t *node, fifo_t *fifo) { star_arg_t *sarg = NODE_SPEC(node, star); trace(__func__); if (!sarg->stopping) { sarg->stopping = 1; SNetStopStream(sarg->instance, fifo); } else if (sarg->stopping == 1) { sarg->stopping = 2; SNetStopStream(sarg->collector, fifo); SNetExprListDestroy(sarg->guards); SNetVariantListDestroy(sarg->exit_patterns); SNetEntityDestroy(sarg->entity); SNetDelete(node); } }
/* Destroy a dripback node. */ void SNetStopDripBack(node_t *node, fifo_t *fifo) { dripback_arg_t *darg = NODE_SPEC(node, dripback); trace(__func__); if (darg->stopping == 0) { darg->stopping = 1; SNetStopStream(darg->instance, fifo); } else if (darg->stopping == 1) { darg->stopping = 2; SNetStopStream(darg->output, fifo); SNetVariantListDestroy(darg->back_patterns); SNetExprListDestroy(darg->guards); SNetStreamDestroy(darg->selfref); SNetEntityDestroy(darg->entity); SNetDelete(node); } }
/** * 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); }
static void BoxTask(snet_entity_t *ent, void *arg) { #ifdef DBG_RT_TRACE_BOX_TIMINGS static struct timeval tv_in; static struct timeval tv_out; #endif #ifdef SNET_DEBUG_COUNTERS snet_time_t time_in; snet_time_t time_out; long mseconds; #endif /* SNET_DEBUG_COUNTERS */ box_arg_t *barg = (box_arg_t *)arg; snet_record_t *rec; snet_stream_desc_t *instream, *outstream; bool terminate = false; instream = SNetStreamOpen(barg->input, 'r'); outstream = SNetStreamOpen(barg->output, 'w'); /* set out descriptor */ barg->hnd.out_sd = outstream; /* set entity */ barg->hnd.ent = ent; /* MAIN LOOP */ while(!terminate) { /* read from input stream */ rec = SNetStreamRead(instream); switch(SNetRecGetDescriptor(rec)) { case REC_trigger_initialiser: case REC_data: barg->hnd.rec = rec; #ifdef DBG_RT_TRACE_BOX_TIMINGS gettimeofday(&tv_in, NULL); SNetUtilDebugNoticeEnt(ent, "[BOX] Firing box function at %lf.", tv_in.tv_sec + tv_in.tv_usec / 1000000.0 ); #endif #ifdef SNET_DEBUG_COUNTERS SNetDebugTimeGetTime(&time_in); #endif /* SNET_DEBUG_COUNTERS */ #ifdef USE_USER_EVENT_LOGGING /* Emit a monitoring message of a record read to be processed by a box */ if (SNetRecGetDescriptor(rec) == REC_data) { SNetThreadingEventSignal(ent, SNetMonInfoCreate(EV_MESSAGE_IN, MON_RECORD, rec) ); } #endif /* execute box function and update execution realm */ barg->hnd = *barg->boxfun(&barg->hnd); barg->hnd = *barg->exerealm_update(&barg->hnd); /* * Emit an event here? * SNetMonInfoEvent(EV_BOX_???, MON_RECORD, rec); */ #ifdef DBG_RT_TRACE_BOX_TIMINGS gettimeofday(&tv_out, NULL); SNetUtilDebugNoticeEnt(ent, "[BOX] Return from box function after %lf sec.", (tv_out.tv_sec - tv_in.tv_sec) + (tv_out.tv_usec - tv_in.tv_usec) / 1000000.0 ); #endif #ifdef SNET_DEBUG_COUNTERS SNetDebugTimeGetTime(&time_out); mseconds = SNetDebugTimeDifferenceInMilliseconds(&time_in, &time_out); SNetDebugCountersIncreaseCounter(mseconds, SNET_COUNTER_TIME_BOX); #endif /* SNET_DEBUG_COUNTERS */ SNetRecDestroy(rec); /* restrict to one data record per execution */ //SNetThreadingYield(); /* check the box task should be migrated after one record execution */ SNetThreadingCheckMigrate(); break; case REC_sync: { snet_stream_t *newstream = SNetRecGetStream(rec); SNetStreamReplace(instream, newstream); SNetRecDestroy(rec); } break; case REC_sort_end: /* forward the sort record */ SNetStreamWrite(outstream, rec); break; case REC_terminate: barg->hnd = *barg->exerealm_destroy(&barg->hnd); SNetStreamWrite(outstream, rec); terminate = true; break; case REC_collect: default: assert(0); } } /* MAIN LOOP END */ barg->hnd = *barg->exerealm_destroy(&barg->hnd); SNetStreamClose(instream, true); SNetStreamClose(outstream, false); /* destroy box arg */ SNetVariantListDestroy(barg->hnd.vars); SNetIntListListDestroy(barg->hnd.sign); SNetMemFree( barg); }
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); }
/** * The feedback dispatcher, at the end of the * feedback combinator loop */ static void FeedbackDispTask(snet_entity_t *ent, void *arg) { fbdisp_arg_t *fbdarg = (fbdisp_arg_t *)arg; snet_stream_desc_t *instream; snet_stream_desc_t *outstream; snet_stream_desc_t *backstream; bool terminate = false; snet_record_t *rec; (void) ent; /* NOT USED */ instream = SNetStreamOpen(fbdarg->in, 'r'); outstream = SNetStreamOpen(fbdarg->out, 'w'); backstream = SNetStreamOpen(fbdarg->fbo, 'w'); /* MAIN LOOP */ while( !terminate) { /* read from input stream */ rec = SNetStreamRead( instream); switch( SNetRecGetDescriptor( rec)) { case REC_data: /* route data record */ if( MatchesBackPattern( rec, fbdarg->back_patterns, fbdarg->guards)) { /* send rec back into the loop */ SNetStreamWrite( backstream, rec); } else { /* send to output */ SNetStreamWrite( outstream, rec); } break; case REC_sort_end: { int lvl = SNetRecGetLevel(rec); if ( 0 == lvl ) { SNetStreamWrite( backstream, rec); } else { assert( lvl > 0 ); SNetRecSetLevel( rec, lvl-1); SNetStreamWrite( outstream, rec); } } break; case REC_terminate: terminate = true; #ifndef FEEDBACK_OMIT_BUFFER /* a terminate record is sent in the backloop for the buffer */ SNetStreamWrite( backstream, SNetRecCopy( rec)); #endif SNetStreamWrite( outstream, rec); break; case REC_sync: SNetStreamReplace( instream, SNetRecGetStream( rec)); SNetRecDestroy( rec); break; case REC_collect: default: assert(0); /* if ignoring, at least destroy ... */ SNetRecDestroy( rec); break; } } /* END OF MAIN LOOP */ SNetStreamClose(instream, true); SNetStreamClose(outstream, false); SNetStreamClose(backstream, false); SNetVariantListDestroy( fbdarg->back_patterns); SNetExprListDestroy( fbdarg->guards); SNetMemFree( fbdarg); }
/* 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; }