snet_stream_t *SNetRouteUpdate(snet_info_t *info, snet_stream_t *in, int loc)
{
  int *counter = (int*) SNetInfoGetTag(info, infoCounter);
  snet_dest_t *dest = (snet_dest_t*) SNetInfoGetTag(info, prevDest);

  if (dest->node != loc) {
    dest->dest = (*counter)++;

    if (SNetDistribIsNodeLocation(dest->node)) {
      dest->node = loc;
      SNetOutputManagerNewOut(*dest, in);

      in = NULL;
    } else if (SNetDistribIsNodeLocation(loc)) {
      if (in == NULL) in = SNetStreamCreate(0);

      SNetInputManagerNewIn(*dest, in);
      dest->node = loc;
    } else {
      dest->node = loc;
    }
  }

  return in;
}
Beispiel #2
0
/**
 * 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;
}
Beispiel #3
0
/**
 * Create the instance of the operand network, including
 * routing component (star incarnate) at the end
 */
static void CreateOperandNetwork(snet_stream_desc_t **next,
    star_arg_t *sarg, snet_stream_desc_t *to_coll)
{
  /* info structure for network creation */
  /* The outstream to the collector from a newly created incarnate.
     Nothing is written to this stream, but it has to be registered
     at the collector. */
  snet_stream_t *starstream, *nextstream_addr;
  /* Create the stream to the instance */
  nextstream_addr = SNetStreamCreate(0);

  /* Set the source of the stream to support garbage collection */
  SNetStreamSetSource(nextstream_addr, SNetLocvecGet(sarg->info));

  /* open the stream for the caller */
  *next = SNetStreamOpen(nextstream_addr, 'w');

  /* use custom creation function for proper/easier update of locvec */
  starstream = SNetSerialStarchild(
      nextstream_addr,
      sarg->info,
      sarg->location,
      sarg->box,
      sarg->selffun
      );

  /* notify collector about the new instance */
  SNetStreamWrite( to_coll, SNetRecCreate(REC_collect, starstream));
}
Beispiel #4
0
/* 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;
}
Beispiel #5
0
/**
 * 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;
}
Beispiel #6
0
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);
}
Beispiel #7
0
/**
 * 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;
}
Beispiel #8
0
/**
 * 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 */
Beispiel #9
0
/**
 * 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);
}
Beispiel #10
0
/**
 * 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;
}
Beispiel #11
0
/**
 * Main starting entry point of the SNet program
 */
int SNetInRun(int argc, char **argv,
              char *static_labels[], int number_of_labels,
              char *static_interfaces[], int number_of_interfaces,
              snet_startup_fun_t fun)
{
  FILE *input = stdin;
  FILE *output = stdout;
  snet_stream_t *input_stream = NULL;
  snet_stream_t *output_stream = NULL;
  int i = 0;
  snet_info_t *info = NULL;
  snet_locvec_t *locvec;
  snetin_label_t *labels = NULL;
  snetin_interface_t *interfaces = NULL;
  char *brk;
  char addr[256];
  int len;
  int port;
  
  /* Parse argv: */
  for(i = 1; i < argc; i++) {
    if(strcmp(argv[i], "-h") == 0) {
      /* Help */
      SNetRuntimeHelpText();

      if(input != stdin && input != NULL) {
	SNetInClose(input);
      }

      if(output != stdout && output != NULL) {
	SNetInClose(output);
      }

      return 0;

    } else if(strcmp(argv[i], "-i") == 0 && input == stdin && i + 1 <= argc) {
      /* Input from file */
      i = i + 1;
      input =  SNetInOpenFile(argv[i], "r");
    } else if(strcmp(argv[i], "-I") == 0 && input == stdin && i + 1 <= argc) {
      /* Input from socket */
      i = i + 1;
      input = SNetInOpenInputSocket(atoi(argv[i]));
    } else if(strcmp(argv[i], "-o") == 0 && output == stdout && i + 1 <= argc) {
      /* Output to file */
      i = i + 1;
      output = SNetInOpenFile(argv[i], "w");
    } else if(strcmp(argv[i], "-O") == 0 && output == stdout && i + 1 <= argc) {
      /* Output to socket */
      i = i + 1;
      brk = strchr(argv[i], ':');

      if(brk == NULL) {
	output = NULL;

	SNetUtilDebugFatal("Could not parse URL!\n");
      }

      len = brk - argv[i];
      strncpy((char *)addr, (const char *)argv[i], len);
      addr[len] = '\0';
      port = atoi(brk + 1);

      output = SNetInOpenOutputSocket(addr, port);
    }
  }

  if(input == NULL) {

    if(output != stdout && output != NULL) {
      SNetInClose(output);
    }

    SNetUtilDebugFatal("");
  }

  if(output == NULL) {

    if(input != stdin && input != NULL) {
      SNetInClose(input);
    }

    SNetUtilDebugFatal("");
  }


  /* Actual SNet network interface main: */

  /* check for number of interfaces */
  if (0 == number_of_interfaces) {
    SNetUtilDebugNotice("No language interfaces were specified by the source program!");
    exit(1);
  }
  
  labels     = SNetInLabelInit(static_labels, number_of_labels);
  interfaces = SNetInInterfaceInit(static_interfaces, number_of_interfaces);

  info = SNetInfoInit();


  SNetDistribInit(argc, argv, info);

  (void) SNetThreadingInit(argc, argv);

  //SNetObserverInit(labels, interfaces); 

  locvec = SNetLocvecCreate();
  SNetLocvecSet(info, locvec);

  SNetDistribStart();

  if (SNetDistribIsRootNode()) {
    input_stream = SNetStreamCreate(0);
    output_stream = fun(input_stream, info, 0);
    output_stream = SNetRouteUpdate(info, output_stream, 0);
    
    /* create output thread */
    SNetInOutputInit(output, labels, interfaces, output_stream);

    /* create input thread */
    SNetInInputInit(input, labels, interfaces, input_stream); 
    
    SNetRuntimeStartWait(input_stream, info, output_stream);  
    
    /* tell the threading layer that it is ok to shutdown,
     and wait until it has stopped such that it can be cleaned up */
    (void) SNetThreadingStop();
  }

  (void) SNetThreadingCleanup();
  SNetInfoDestroy(info);

  SNetLocvecDestroy(locvec);

  /* destroy observers */
  //SNetObserverDestroy();

  SNetInLabelDestroy(labels);
  SNetInInterfaceDestroy(interfaces);

  if(input != stdin) {
    SNetInClose(input);
  }

  if(output != stdout) {
    SNetInClose(output);
  }

  return 0;
}
Beispiel #12
0
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);
}
Beispiel #13
0
/**
 * 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);
}
Beispiel #14
0
/**
 * Main starting entry point of the SNet program
 */
int SNetInRun(int argc, char **argv,
              char *static_labels[], int number_of_labels,
              char *static_interfaces[], int number_of_interfaces,
              snet_startup_fun_t fun)
{
  FILE *input = NULL;
  FILE *output = NULL;
  snet_stream_t *input_stream = NULL;
  snet_stream_t *output_stream = NULL;
  snet_info_t *info;
  snet_locvec_t *locvec;
  snetin_label_t *labels = NULL;
  snetin_interface_t *interfaces = NULL;

  if (0 == SNetInParseOptions(argc, argv, &input, &output)) {
    return 0;
  }

  /* Actual SNet network interface main: */

  /* check for number of interfaces */
  if (0 == number_of_interfaces) {
    SNetUtilDebugNotice("No language interfaces were specified by the source program!");
    exit(1);
  }

  labels     = SNetInLabelInit(static_labels, number_of_labels);
  interfaces = SNetInInterfaceInit(static_interfaces, number_of_interfaces);

  info = SNetInfoInit();

  SNetDistribInit(argc, argv, info);

  (void) SNetThreadingInit(argc, argv);

  SNetObserverInit(labels, interfaces);

  locvec = SNetLocvecCreate();
  SNetLocvecSet(info, locvec);

  input_stream = SNetStreamCreate(0);
  output_stream = fun(input_stream, info, 0);
  output_stream = SNetRouteUpdate(info, output_stream, 0);

  SNetDistribStart();

  if (SNetDistribIsRootNode()) {
    /* create output thread */
    SNetInOutputInit(output, labels, interfaces, output_stream);

    /* create input thread */
    SNetInInputInit(input, labels, interfaces, input_stream);
  }

  SNetRuntimeStartWait(input_stream, info, output_stream);

  /* tell the threading layer that it is ok to shutdown,
     and wait until it has stopped such that it can be cleaned up */
  (void) SNetThreadingStop();

  (void) SNetThreadingCleanup();

  SNetInfoDestroy(info);

  SNetLocvecDestroy(locvec);

  /* destroy observers */
  SNetObserverDestroy();

  SNetInLabelDestroy(labels);
  SNetInInterfaceDestroy(interfaces);

  if(input != stdin) {
    SNetInClose(input);
  }

  if(output != stdout) {
    SNetInClose(output);
  }

  return 0;
}
Beispiel #15
0
/* 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;
}
Beispiel #16
0
/**
 * 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;
}