void SNetDistribUnblockDest(snet_dest_t dest) { mpi_buf_t buf = {0, 0, NULL}; PackDest(&buf, &dest); MPISend(buf.data, buf.offset, dest.node, snet_unblock); SNetMemFree(buf.data); }
void SNetDistribFetchRef(snet_ref_t *ref) { mpi_buf_t buf = {0, 0, NULL}; SNetRefSerialise(ref, &buf, &PackInt, &PackByte); MPISend(buf.data, buf.offset, SNetRefNode(ref), snet_ref_fetch); SNetMemFree(buf.data); }
void SNetStreamClose(snet_stream_desc_t *sd, int destroy_s) { if (destroy_s) { SNetStreamDestroy(sd->stream); } SNetMemFree(sd); }
void SNetDistribSendData(snet_ref_t *ref, void *data, void *dest) { mpi_buf_t buf = {0, 0, NULL}; SNetRefSerialise(ref, &buf, &PackInt, &PackByte); SNetInterfaceGet(SNetRefInterface(ref))->packfun(data, &buf); MPISend(buf.data, buf.offset, (uintptr_t) dest, snet_ref_set); SNetMemFree(buf.data); }
void SNetDistribUpdateRef(snet_ref_t *ref, int count) { mpi_buf_t buf = {0, 0, NULL}; SNetRefSerialise(ref, &buf, &PackInt, &PackByte); PackInt(&buf, 1, &count); MPISend(buf.data, buf.offset, SNetRefNode(ref), snet_ref_update); SNetMemFree(buf.data); }
void SNetDistribUpdateRef(snet_ref_t *ref, int count) { mpi_buf_t buf = {0, 0, NULL}; SNetRefSerialise(ref, &buf); SNetDistribPack(&buf, &count, sizeof(count)); MPISendBuf(&buf, SNetRefNode(ref), snet_ref_update); SNetMemFree(buf.data); }
void SNetDistribWaitExit(snet_info_t *info) { pthread_mutex_lock(&exitMutex); while (running) pthread_cond_wait(&exitCond, &exitMutex); pthread_mutex_unlock(&exitMutex); SNetMemFree((int*) SNetInfoDelTag(info, infoCounter)); }
/* Frees the memory allocated for c4snet_data_t struct. */ void C4SNetFree(c4snet_data_t *data) { if (--data->ref_count == 0) { if (data->vtype == VTYPE_array) MemFree(data->data.ptr); SNetMemFree(data); } }
void SNetRouteDynamicExit(snet_info_t *info, int dynamicIndex, int dynamicLoc, snet_startup_fun_t fun) { int *counter = (int*) SNetInfoDelTag(info, infoCounter); (void) dynamicIndex; /* NOT USED */ (void) dynamicLoc; /* NOT USED */ (void) fun; /* NOT USED */ SNetMemFree(counter); SNetInfoSetTag(info, infoCounter, (uintptr_t) NULL, NULL); return; }
static void SAC4SNetMPIPackFun(void *sacdata, void *buf) { int *shape; void *contents = NULL; SACarg *data = sacdata; int type, dims, num_elems = 1; type = SACARGgetBasetype(data); dims = SACARGgetDim(data); shape = SNetMemAlloc(dims * sizeof(int)); for (int i = 0; i < dims; i++) { shape[i] = SACARGgetShape(data, i); num_elems *= SACARGgetShape(data, i); } SNetDistribPack(&type, buf, MPI_INT, 1); SNetDistribPack(&dims, buf, MPI_INT, 1); SNetDistribPack(shape, buf, MPI_INT, dims); SNetMemFree(shape); switch (type) { case SACint: contents = SACARGconvertToIntArray(SACARGnewReference(data)); break; case SACdbl: contents = SACARGconvertToDoubleArray(SACARGnewReference(data)); break; case SACflt: contents = SACARGconvertToFloatArray(SACARGnewReference(data)); break; default: Error( "Unsupported basetype in pack function."); break; } SNetDistribPack(contents, buf, SAC4SNetBasetypeToMPIType(type), num_elems); SNetMemFree(contents); }
void SNetRecDestroy( snet_record_t *rec) { int name; snet_ref_t *field; switch (REC_DESCR( rec)) { case REC_data: RECORD_FOR_EACH_FIELD(rec, name, field) { SNetRefDestroy(field); } SNetRefMapDestroy( DATA_REC( rec, fields)); SNetIntMapDestroy( DATA_REC( rec, tags)); SNetIntMapDestroy( DATA_REC( rec, btags)); if (DATA_REC( rec, parent_rids) != NULL) SNetRecIdListDestroy( DATA_REC( rec, parent_rids)); SNetMemFree( RECORD( rec, data_rec)); break; case REC_sync: { snet_variant_t *var = SYNC_REC( rec, outtype); if (var != NULL) { SNetVariantDestroy(var); } SNetMemFree( RECORD( rec, sync_rec)); } break; case REC_collect: SNetMemFree( RECORD( rec, coll_rec)); break; case REC_sort_end: SNetMemFree( RECORD( rec, sort_end_rec)); break; case REC_terminate: SNetMemFree( RECORD( rec, terminate_rec)); break; case REC_trigger_initialiser: break; default: SNetUtilDebugFatal("Unknown record description, in SNetRecDestroy"); break; }
static void DestroyUsrdata(lpel_stream_t * ls) { usrdata_t *dat = LpelStreamGetUsrData(ls); if (dat != NULL) { if (dat->source != NULL) { SNetLocvecDestroy(dat->source); } /* nothing to do for callback */ /* free the usrdat container itself */ SNetMemFree(dat); LpelStreamSetUsrData(ls, NULL); } }
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); }
snet_msg_t SNetDistribRecvMsg(void) { int count; snet_msg_t result; MPI_Status status; static mpi_buf_t recvBuf = {0, 0, NULL}; MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status); MPI_Get_count(&status, MPI_PACKED, &count); MPI_Pack_size(count, MPI_PACKED, MPI_COMM_WORLD, &recvBuf.offset); if ((unsigned) recvBuf.offset > recvBuf.size) { SNetMemFree(recvBuf.data); recvBuf.data = SNetMemAlloc(recvBuf.offset); recvBuf.size = recvBuf.offset; } MPI_Recv(recvBuf.data, count, MPI_PACKED, MPI_ANY_SOURCE, status.MPI_TAG, MPI_COMM_WORLD, &status); recvBuf.offset = 0; result.type = status.MPI_TAG; switch (result.type) { case snet_rec: result.rec = SNetRecDeserialise(&recvBuf, &UnpackInt, &UnpackRef); case snet_block: case snet_unblock: result.dest.node = status.MPI_SOURCE; UnpackDest(&recvBuf, &result.dest); break; case snet_ref_set: result.ref = SNetRefDeserialise(&recvBuf, &UnpackInt, &UnpackByte); result.data = (uintptr_t) SNetInterfaceGet(SNetRefInterface(result.ref))->unpackfun(&recvBuf); break; case snet_ref_fetch: result.ref = SNetRefDeserialise(&recvBuf, &UnpackInt, &UnpackByte); result.data = status.MPI_SOURCE; break; case snet_ref_update: result.ref = SNetRefDeserialise(&recvBuf, &UnpackInt, &UnpackByte); UnpackInt(&recvBuf, 1, &result.val); break; default: break; } return result; }
/* Frees the memory allocated for c4snet_data_t struct. */ void C4SNetFree(c4snet_data_t *data) { #if HAVE_SYNC_ATOMIC_BUILTINS /* Temporary fix for race condition: */ unsigned int refs = FAS(&data->ref_count, 1); assert(refs > 0); if (refs == 1) #else /* Old code, which contains a race condition: */ if (--data->ref_count == 0) #endif { if (data->vtype == VTYPE_array) MemFree(data->data.ptr); SNetMemFree(data); } }
static void FeedbackBufTask(snet_entity_t *, void *arg) { fbbuf_arg_t *fbbarg = (fbbuf_arg_t *)arg; snet_stream_desc_t *instream; snet_stream_desc_t *outstream; snet_record_t *rec; int out_counter = 0; int out_capacity; instream = SNetStreamOpen(fbbarg->in, 'r'); outstream = SNetStreamOpen(fbbarg->out, 'w'); out_capacity = fbbarg->out_capacity; SNetMemFree( fbbarg); /* MAIN LOOP */ while(1) { rec = SNetStreamRead(instream); if( SNetRecGetDescriptor(rec) == REC_terminate ) { /* this means, the outstream does not exist anymore! */ SNetRecDestroy(rec); break; /* exit main loop */ } if (out_counter+1 >= out_capacity) { /* new stream */ snet_stream_t *new_stream = SNetStreamCreate(out_capacity); SNetStreamWrite(outstream, SNetRecCreate(REC_sync, new_stream) ); SNetStreamClose(outstream, false); outstream = SNetStreamOpen(new_stream, 'w'); out_counter = 0; } /* write the record to the stream */ SNetStreamWrite(outstream, rec); out_counter++; } /* END OF MAIN LOOP */ SNetStreamClose(instream, true); SNetStreamClose(outstream, false); }
void SNetDistribZMQPack(zframe_t **dstframe, void *src, size_t count) { if (*dstframe != NULL) { size_t src_size = count; size_t dstframe_size = zframe_size(*dstframe); byte *dstframe_data = zframe_data(*dstframe); byte *newsrc = SNetMemAlloc(src_size + dstframe_size); memcpy(newsrc, dstframe_data, dstframe_size); memcpy(newsrc + dstframe_size, src, src_size); zframe_reset(*dstframe, newsrc, dstframe_size + src_size); SNetMemFree(newsrc); } else { *dstframe = zframe_new(src, count); } }
/** * This is the task doing the global input */ static void GlobInputTask(snet_entity_t *ent, void* data) { handle_t *hnd = (handle_t *)data; if(hnd->buffer != NULL) { int i; snet_stream_desc_t *outstream = SNetStreamOpen(hnd->buffer, 'w'); SNetInParserInit( hnd->file, hnd->labels, hnd->interfaces, outstream, ent); i = SNET_PARSE_CONTINUE; while(i != SNET_PARSE_TERMINATE){ i = SNetInParserParse(); } SNetInParserDestroy(); SNetStreamClose( outstream, false); } SNetMemFree(hnd); }
void SNetDistribSendData(snet_ref_t *ref, void *data, void *dest) { int node; lut_addr_t addr; snet_comm_type_t type = snet_ref_set; if (remap) { addr.node = *(int*) dest; } else { addr = *(lut_addr_t*) dest; SNetMemFree(dest); } node = addr.node; start_write_node(node); cpy_mem_to_mpb(node, &type, sizeof(snet_comm_type_t)); SNetRefSerialise(ref, (void*) node, &PackInt, &PackByte); if (!remap) cpy_mem_to_mpb(node, &addr, sizeof(lut_addr_t)); SNetInterfaceGet(SNetRefInterface(ref))->packfun(data, &addr); stop_write_node(node); }
static void *SAC4SNetMPIUnpackFun(void *buf) { int *shape; SACarg *result = NULL; void *contents = NULL; int type, dims, num_elems = 1; SNetDistribUnpack(buf, &type, sizeof(type)); SNetDistribUnpack(buf, &dims, sizeof(dims)); shape = SNetMemAlloc(dims * sizeof(int)); SNetDistribUnpack(buf, shape, dims * sizeof(int)); for (int i = 0; i < dims; i++) { num_elems *= shape[i]; } contents = SNetMemAlloc(num_elems * sizeOfType(type)); SNetDistribUnpack(buf, contents, num_elems * sizeOfType(type)); switch (type) { case SACint: result = SACARGconvertFromIntPointerVect(contents, dims, shape); break; case SACflt: result = SACARGconvertFromFloatPointerVect(contents, dims, shape); break; case SACdbl: result = SACARGconvertFromDoublePointerVect(contents, dims, shape); break; default: Error( "Unsupported basetype in unpack function."); break; } SNetMemFree(shape); return result; }
/** * The feedback collector, the entry point of the * feedback combinator loop */ static void FeedbackCollTask(snet_entity_t *ent, void *arg) { fbcoll_arg_t *fbcarg = (fbcoll_arg_t *)arg; struct fbcoll_state state; (void) ent; /* NOT USED */ /* initialise state */ state.terminate = false; state.mode = FBCOLL_IN; state.instream = SNetStreamOpen(fbcarg->in, 'r'); state.backstream = SNetStreamOpen(fbcarg->fbi, 'r'); state.outstream = SNetStreamOpen(fbcarg->out, 'w'); SNetMemFree( fbcarg); /* MAIN LOOP */ while( !state.terminate) { /* which stream to read from is mode dependent */ switch(state.mode) { case FBCOLL_IN: FbCollReadIn(&state); break; case FBCOLL_FB1: case FBCOLL_FB0: FbCollReadFbi(&state); break; default: assert(0); /* should not be reached */ } } /* END OF MAIN LOOP */ SNetStreamClose(state.instream, true); SNetStreamClose(state.backstream, true); SNetStreamClose(state.outstream, false); }
/* This function prints records to stdout */ static void printRec(snet_record_t *rec, handle_t *hnd) { snet_ref_t *field; int name, val; char *label = NULL; char *interface = NULL; snet_record_mode_t mode; /* Change this to redirect the output! */ if (rec != NULL) { fprintf(hnd->file, "<?xml version=\"1.0\" ?>\n"); switch( SNetRecGetDescriptor( rec)) { case REC_data: mode = SNetRecGetDataMode(rec); if (mode == MODE_textual) { fprintf(hnd->file, "<record xmlns=\"snet-home.org\" type=\"data\" mode=\"textual\" >\n"); } else { fprintf(hnd->file, "<record xmlns=\"snet-home.org\" type=\"data\" mode=\"binary\" >\n"); } /* Fields */ RECORD_FOR_EACH_FIELD(rec, name, field) { int id = SNetRecGetInterfaceId(rec); if((label = SNetInIdToLabel(hnd->labels, name)) != NULL){ if((interface = SNetInIdToInterface(hnd->interfaces, id)) != NULL) { fprintf(hnd->file, "<field label=\"%s\" interface=\"%s\">", label, interface); if(mode == MODE_textual) { SNetInterfaceGet(id)->serialisefun(hnd->file, SNetRefGetData(field)); } else { SNetInterfaceGet(id)->encodefun(hnd->file, SNetRefGetData(field)); } fprintf(hnd->file, "</field>\n"); SNetMemFree(interface); } SNetMemFree(label); } else{ SNetUtilDebugFatal("Unknown field %d at output!", name); } } /* Tags */ RECORD_FOR_EACH_TAG(rec, name, val) { if ((label = SNetInIdToLabel(hnd->labels, name)) != NULL) { fprintf(hnd->file, "<tag label=\"%s\">%d</tag>\n", label, val); } else{ SNetUtilDebugFatal("Unknown tag %d at output!", name); } SNetMemFree(label); } /* BTags */ RECORD_FOR_EACH_BTAG(rec, name, val) { if ((label = SNetInIdToLabel(hnd->labels, name)) != NULL){ fprintf(hnd->file, "<btag label=\"%s\">%d</btag>\n", label, val); } else{ SNetUtilDebugFatal("Unknown binding tag %d at output!", name); } SNetMemFree(label); } fprintf(hnd->file, "</record>\n"); break; case REC_sync: SNetUtilDebugFatal("REC_sync in output! This should not happen."); break; case REC_collect: SNetUtilDebugFatal("REC_collect in output! This should not happen."); break; case REC_sort_end: SNetUtilDebugFatal("REC_sort_end in output! This should not happen."); break; case REC_trigger_initialiser: SNetUtilDebugFatal("REC_trigger_initializer in output! This should not happen."); break; case REC_terminate: fprintf(hnd->file, "<record type=\"terminate\" />"); break; default: break; }
static void SAC4SNetDataSerialise( FILE *file, void *ptr) { int i, dim; SACarg *ret, *arg = (SACarg*)ptr; char *basetype_str; int btype; btype = SACARGgetBasetype( arg); if( btype <= MaxTNum()) { basetype_str = SNetMemAlloc( (strlen( t_descr[ btype]) + 1) * sizeof( char)); strcpy( basetype_str, t_descr[ btype]); } else { basetype_str = SNetMemAlloc( (strlen( "(UDT)") + 1) * sizeof( char)); strcpy( basetype_str, "(UDT)"); } if( arg != NULL) { dim = SACARGgetDim( arg); fprintf( file, "\n%s %s %d ", IDSTRINGPRE, basetype_str, dim); for( i=0; i<dim; i++) { fprintf( file, "%d ",SACARGgetShape( arg, i)); } fprintf(file, " %s\n", IDSTRINGSUF); /* create a stub hive for the SAC calls */ SAC_AttachHive(SAC_AllocHive(1, 2, NULL, NULL)); switch( SACARGgetBasetype( arg)) { case T_int: SAC4SNetFibreIO__PrintIntArray2( &ret, SACARGconvertFromVoidPointer( SACTYPE_StdIO_File, file), SACARGnewReference( arg)); break; case T_float: SAC4SNetFibreIO__PrintFloatArray2( &ret, SACARGconvertFromVoidPointer( SACTYPE_StdIO_File, file), SACARGnewReference( arg)); break; case T_double: SAC4SNetFibreIO__PrintDoubleArray2( &ret, SACARGconvertFromVoidPointer( SACTYPE_StdIO_File, file), SACARGnewReference( arg)); break; default: fprintf( file, "## UNSERIALISABLE BASETYPE (%d) ##\n", btype); break; } /* release the stub hive */ SAC_ReleaseHive(SAC_DetachHive()); } SNetMemFree( basetype_str); }
/** * Split box task. * * Implements both the non-deterministic and deterministic variants. */ static void SplitBoxTask(snet_entity_t *ent, void *arg) { int i; split_arg_t *sarg = (split_arg_t *)arg; snet_stream_desc_t *initial, *instream; int ltag_val, utag_val; snet_info_t *info; snet_record_t *rec; snet_locvec_t *locvec; bool terminate = false; /* a list of all outstreams for all yet created instances */ snet_streamset_t repos_set = NULL; snet_stream_iter_t *iter = SNetStreamIterCreate( &repos_set); /* a hashtable for fast lookup, initial capacity = 2^4 = 16 */ hashtab_t *repos_tab = HashtabCreate( 4); (void) ent; /* NOT USED */ /* for deterministic variant: */ int counter = 0; initial = SNetStreamOpen(sarg->output, 'w'); instream = SNetStreamOpen(sarg->input, 'r'); /* MAIN LOOP START */ while( !terminate) { /* read from input stream */ rec = SNetStreamRead( instream); switch( SNetRecGetDescriptor( rec)) { case REC_data: /* get lower and upper tag values */ ltag_val = SNetRecGetTag( rec, sarg->ltag); utag_val = SNetRecGetTag( rec, sarg->utag); /* for all tag values */ for( i = ltag_val; i <= utag_val; i++) { snet_stream_desc_t *outstream = HashtabGet( repos_tab, i); if( outstream == NULL) { snet_stream_t *temp_stream; snet_stream_t *newstream_addr = SNetStreamCreate(0); /* instance does not exist yet, create it */ outstream = SNetStreamOpen(newstream_addr, 'w'); /* add to lookup table */ HashtabPut( repos_tab, i, outstream); /* add to list */ SNetStreamsetPut( &repos_set, outstream); /* create info and location vector for creation of this replica */ info = SNetInfoCopy(sarg->info); locvec = SNetLocvecSplitSpawn(SNetLocvecGet(sarg->info), i); SNetLocvecSet(info, locvec); if( sarg->is_byloc) { SNetRouteDynamicEnter(info, i, i, sarg->boxfun); temp_stream = sarg->boxfun(newstream_addr, info, i); temp_stream = SNetRouteUpdate(info, temp_stream, sarg->location); SNetRouteDynamicExit(info, i, i, sarg->boxfun); } else { SNetRouteDynamicEnter(info, i, sarg->location, sarg->boxfun); temp_stream = sarg->boxfun(newstream_addr, info, sarg->location); temp_stream = SNetRouteUpdate(info, temp_stream, sarg->location); SNetRouteDynamicExit(info, i, sarg->location, sarg->boxfun); } /* destroy info and location vector */ SNetLocvecDestroy(locvec); SNetInfoDestroy(info); if(temp_stream != NULL) { /* notify collector about the new instance via initial */ SNetStreamWrite( initial, SNetRecCreate( REC_collect, temp_stream)); } } /* end if (outstream==NULL) */ /* multicast the record */ SNetStreamWrite( outstream, /* copy record for all but the last tag value */ (i!=utag_val) ? SNetRecCopy( rec) : rec ); } /* end for all tags ltag_val <= i <= utag_val */ /* If deterministic, append a sort record to *all* registered * instances and the initial stream. */ if( sarg->is_det ) { /* reset iterator */ SNetStreamIterReset( iter, &repos_set); while( SNetStreamIterHasNext( iter)) { snet_stream_desc_t *cur_stream = SNetStreamIterNext( iter); SNetStreamWrite( cur_stream, SNetRecCreate( REC_sort_end, 0, counter)); } /* Now also send a sort record to initial, after the collect records for new instances have been sent */ SNetStreamWrite( initial, SNetRecCreate( REC_sort_end, 0, counter)); } /* increment counter for deterministic variant */ counter += 1; break; case REC_sync: { snet_stream_t *newstream = SNetRecGetStream( rec); SNetStreamReplace( instream, newstream); SNetRecDestroy( rec); } break; case REC_sort_end: /* broadcast the sort record */ SNetStreamIterReset( iter, &repos_set); /* all instances receive copies of the record */ while( SNetStreamIterHasNext( iter)) { snet_stream_desc_t *cur_stream = SNetStreamIterNext( iter); SNetStreamWrite( cur_stream, SNetRecCreate( REC_sort_end, /* we have to increase level */ SNetRecGetLevel( rec)+1, SNetRecGetNum( rec)) ); } /* send the original record to the initial stream, but with increased level */ SNetRecSetLevel( rec, SNetRecGetLevel( rec) + 1); SNetStreamWrite( initial, rec); break; case REC_terminate: SNetStreamIterReset( iter, &repos_set); /* all instances receive copies of the record */ while( SNetStreamIterHasNext( iter)) { snet_stream_desc_t *cur_stream = SNetStreamIterNext( iter); SNetStreamWrite( cur_stream, SNetRecCopy( rec)); SNetStreamIterRemove( iter); /* close the stream to the instance */ SNetStreamClose( cur_stream, false); } /* send the original record to the initial stream */ SNetStreamWrite( initial, rec); /* note that no sort record has to be appended */ terminate = true; break; case REC_collect: /* invalid control record */ default: assert( 0); /* if ignore, at least destroy it */ SNetRecDestroy( rec); } } /* MAIN LOOP END */ /* destroy repository */ HashtabDestroy( repos_tab); SNetStreamIterDestroy( iter); /* close and destroy initial stream */ SNetStreamClose( initial, false); /* close instream */ SNetStreamClose( instream, true); SNetLocvecDestroy(SNetLocvecGet(sarg->info)); SNetInfoDestroy(sarg->info); /* destroy the argument */ SNetMemFree( sarg); } /* END of SPLIT BOX TASK */
snet_msg_t SNetDistribRecvMsg(void) { lut_addr_t addr; snet_msg_t result; static sigset_t sigmask; static bool handling = true, set = false; if (!set) { set = true; write_pid(); sigemptyset(&sigmask); sigaddset(&sigmask, SIGUSR1); sigaddset(&sigmask, SIGUSR2); } start: if (!handling) { sigwait(&sigmask, &result.val); if (result.val == SIGUSR2) { result.type = snet_update; return result; } } lock(node_location); flush(); if (START(node_location) == END(node_location)) { handling = false; HANDLING(node_location) = 0; FOOL_WRITE_COMBINE; unlock(node_location); goto start; } else if (!handling) { handling = true; HANDLING(node_location) = 1; FOOL_WRITE_COMBINE; } cpy_mpb_to_mem(node_location, &result.type, sizeof(snet_comm_type_t)); switch (result.type) { case snet_rec: result.rec = SNetRecDeserialise((void*) node_location, &UnpackInt, &UnpackRef); case snet_block: case snet_unblock: cpy_mpb_to_mem(node_location, &result.dest, sizeof(snet_dest_t)); break; case snet_ref_set: result.ref = SNetRefDeserialise((void*) node_location, &UnpackInt, &UnpackByte); if (!remap) cpy_mpb_to_mem(node_location, &addr, sizeof(lut_addr_t)); result.data = (uintptr_t) SNetInterfaceGet(SNetRefInterface(result.ref))->unpackfun(&addr); break; case snet_ref_fetch: result.ref = SNetRefDeserialise((void*) node_location, &UnpackInt, &UnpackByte); if (remap) { cpy_mpb_to_mem(node_location, &result.val, sizeof(int)); unlock(node_location); SNetDistribSendData(result.ref, SNetRefGetData(result.ref), &result.val); SNetMemFree(result.ref); goto start; } else { result.data = (uintptr_t) SNetMemAlloc(sizeof(lut_addr_t)); cpy_mpb_to_mem(node_location, (void*) result.data, sizeof(lut_addr_t)); } break; case snet_ref_update: result.ref = SNetRefDeserialise((void*) node_location, &UnpackInt, &UnpackByte); cpy_mpb_to_mem(node_location, &result.val, sizeof(int)); break; default: break; } unlock(node_location); return result; }
/** * 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); }
static void SCCFreeWrapper(void *p) { if (!remap) SNetMemFree(p); SCCFree(p); }
/** * The feedback buffer, in the back-loop */ static void FeedbackBufTask(snet_entity_t *ent, void *arg) { fbbuf_arg_t *fbbarg = (fbbuf_arg_t *)arg; snet_stream_desc_t *instream; snet_stream_desc_t *outstream; snet_queue_t *internal_buffer; snet_record_t *rec; int out_capacity; int max_read; (void) ent; /* NOT USED */ instream = SNetStreamOpen(fbbarg->in, 'r'); outstream = SNetStreamOpen(fbbarg->out, 'w'); out_capacity = fbbarg->out_capacity; SNetMemFree( fbbarg); internal_buffer = SNetQueueCreate(); max_read = out_capacity; /* TODO better usual stream capacity */ /* MAIN LOOP */ while(1) { int n = 0; rec = NULL; /* STEP 1: read n=min(available,max_read) records from input stream */ /* read first record of the actual dispatch */ if (0 == SNetQueueSize(internal_buffer)) { rec = SNetStreamRead(instream); /* only in empty mode! */ if( REC_terminate == SNetRecGetDescriptor( rec)) { /* this means, the outstream does not exist anymore! */ SNetRecDestroy(rec); goto feedback_buf_epilogue; } } else { SNetThreadingYield(); if ( SNetStreamPeek(instream) != NULL ) { rec = SNetStreamRead(instream); assert( REC_terminate != SNetRecGetDescriptor( rec) ); } } if (rec != NULL) { n = 1; /* put record into internal buffer */ (void) SNetQueuePut(internal_buffer, rec); } while ( n<=max_read && SNetStreamPeek(instream)!=NULL ) { rec = SNetStreamRead(instream); /* check if we will need a larger outstream, and if so, * create a larger stream */ if (SNetQueueSize(internal_buffer)+1 >= out_capacity) { snet_stream_t *new_stream; out_capacity *= 2; new_stream = SNetStreamCreate(out_capacity); (void) SNetQueuePut(internal_buffer, SNetRecCreate(REC_sync, new_stream)); } /* put record into internal buffer */ (void) SNetQueuePut(internal_buffer, rec); n++; } /* STEP 2: try to empty the internal buffer */ rec = SNetQueuePeek(internal_buffer); while (rec != NULL) { snet_stream_t *new_stream = NULL; if( REC_sync == SNetRecGetDescriptor( rec)) { new_stream = SNetRecGetStream(rec); } if (0 == SNetStreamTryWrite(outstream, rec)) { snet_record_t *rem; /* success, also remove from queue */ rem = SNetQueueGet(internal_buffer); assert( rem == rec ); if (new_stream != NULL) { /* written sync record, now change stream */ SNetStreamClose(outstream, false); outstream = SNetStreamOpen(new_stream, 'w'); } } else { /* there remain elements in the buffer */ break; } /* for the next iteration */ rec = SNetQueuePeek(internal_buffer); } } /* END OF MAIN LOOP */ feedback_buf_epilogue: SNetQueueDestroy(internal_buffer); SNetStreamClose(instream, true); SNetStreamClose(outstream, false); }
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); }
/** * Collector task for dynamic combinators (star/split) * and the static parallel combinator */ void CollectorTask(snet_entity_t *ent, void *arg) { coll_arg_t *carg = (coll_arg_t *)arg; snet_streamset_t readyset, waitingset; snet_stream_iter_t *wait_iter; snet_stream_desc_t *outstream; snet_stream_desc_t *curstream = NULL; snet_stream_desc_t *last = NULL; // when the paired parallel terminate, it sends the sort_end record to the last branch snet_record_t *sort_rec = NULL; snet_record_t *term_rec = NULL; int incount; bool terminate = false; /* open outstream for writing */ outstream = SNetStreamOpen(carg->output, 'w'); readyset = waitingset = NULL; if (carg->is_static) { int i; incount = CARG_ST(carg, num); /* fill initial readyset of collector */ for (i=0; i<incount; i++) { snet_stream_desc_t *tmp; /* open each stream in listening set for reading */ tmp = SNetStreamOpen( CARG_ST(carg, inputs[i]), 'r'); /* add each stream instreams[i] to listening set of collector */ SNetStreamsetPut( &readyset, tmp); } SNetMemFree( CARG_ST(carg, inputs) ); } else { incount = 1; /* Open initial stream and put into readyset */ SNetStreamsetPut( &readyset, SNetStreamOpen(CARG_DYN(carg, input), 'r') ); } /* create an iterator for waiting set, is reused within main loop*/ wait_iter = SNetStreamIterCreate( &waitingset); /* MAIN LOOP */ while( !terminate) { /* get a record */ snet_record_t *rec = GetRecord(&readyset, incount, &curstream); /* process the record */ switch( SNetRecGetDescriptor( rec)) { case REC_data: /* data record: forward to output */ SNetStreamWrite( outstream, rec); break; case REC_sort_end: /* curstream == last, this is the last branch and the paired parallel already terminates * increase the level by one because it was not increased by the paired parallel as it should be * Also later when last becomes the only waiting branch, the collector should terminate. However before terminating, it should pretend that parallel has sent the sort end from all branches */ if (curstream == last) { // imply last != NULL, this will be the last branch and the paired parallel already terminates SNetRecSetLevel(rec, SNetRecGetLevel(rec) + 1); // increase the level by one because it was not increased by the paired parallel as it should be } if (last == NULL && SNetRecGetLevel(rec) == 0 && SNetRecGetNum(rec) == -1) { // if last was not set, and collector receives a sort_end (l0, c-1) --> set the curstream as last last = curstream; // from now on, any sort_end from last will be increased level by 1 SNetRecDestroy( rec); break; // ignore the sort_end } ProcessSortRecord(ent, rec, &sort_rec, curstream, &readyset, &waitingset); /* end processing this stream */ curstream = NULL; break; case REC_sync: SNetStreamReplace( curstream, SNetRecGetStream( rec)); SNetRecDestroy( rec); break; case REC_collect: /* only for dynamic collectors! */ assert( false == carg->is_static ); /* collect: add new stream to ready set */ #ifdef DESTROY_TERM_IN_WAITING_UPON_COLLECT /* but first, check if we can free resources by checking the waiting set for arrival of termination records */ incount -= DestroyTermInWaitingSet(wait_iter, &waitingset); assert(incount > 0); #endif /* finally, add new stream to ready set */ SNetStreamsetPut( &readyset, SNetStreamOpen( SNetRecGetStream( rec), 'r') ); /* update incoming counter */ incount++; /* destroy collect record */ SNetRecDestroy( rec); break; case REC_terminate: /* termination record: close stream and remove from ready set */ ProcessTermRecord(rec, &term_rec, curstream, &readyset, &incount); /* stop processing this stream */ curstream = NULL; break; default: assert(0); /* if ignore, at least destroy ... */ SNetRecDestroy( rec); } /* end switch */ /************* termination conditions *****************/ if ( SNetStreamsetIsEmpty( &readyset)) { /* the streams which had a sort record are in the waitingset */ if ( !SNetStreamsetIsEmpty( &waitingset)) { if ( carg->is_static && (1 == incount) ) { // stat snet_stream_desc_t *in = (waitingset != NULL) ? waitingset : readyset; /* if last is the only one in the waitingset --> pretends that the already-terminated paired parallel has sent the sort end to all branches * Therefore restore the waitingset before terminating (so that a relevant sort_end is sent out) */ if (in == last) RestoreFromWaitingset(&waitingset, &readyset, &sort_rec, outstream); SNetStreamWrite( outstream, SNetRecCreate( REC_sync, SNetStreamGet(in)) ); SNetStreamClose( in, false); terminate = true; #ifdef DEBUG_PRINT_GC /* terminating due to GC */ SNetUtilDebugNoticeEnt( ent, "[COLL] Terminate static collector as only one branch left!" ); #endif } else RestoreFromWaitingset(&waitingset, &readyset, &sort_rec, outstream); } else { /* both ready set and waitingset are empty */ #ifdef DEBUG_PRINT_GC if (carg->is_static) { SNetUtilDebugNoticeEnt( ent, "[COLL] Terminate static collector as no inputs left!"); } #endif assert(term_rec != NULL); SNetStreamWrite( outstream, term_rec); term_rec = NULL; terminate = true; } } /************* end of termination conditions **********/ } /* MAIN LOOP END */ if (term_rec != NULL) { SNetRecDestroy(term_rec); } if (sort_rec != NULL) { SNetRecDestroy(sort_rec); } /* close outstream */ SNetStreamClose( outstream, false); /* destroy iterator */ SNetStreamIterDestroy( wait_iter); /* destroy argument */ SNetMemFree( carg); } /* END of DYNAMIC COLLECTOR TASK */