Example #1
0
/* Star component: forward record to instance or to collector. */
void SNetNodeStar(snet_stream_desc_t *desc, snet_record_t *rec)
{
  const star_arg_t      *sarg = DESC_NODE_SPEC(desc, star);
  landing_star_t        *land = DESC_LAND_SPEC(desc, star);

  trace(__func__);

  switch (REC_DESCR(rec)) {
    case REC_data:
      if (land->star_leader && (sarg->is_det | sarg->is_detsup)) {
        SNetDetEnter(rec, &land->detenter, sarg->is_det, sarg->entity);
      }
      if (MatchesExitPattern( rec, sarg->exit_patterns, sarg->guards)) {
        StarWrite(WriteCollector, rec, desc);
      } else {
        StarWrite(WriteInstance, rec, desc);
      }
      break;

    case REC_detref:
      /* Forward record */
      StarWrite(WriteCollector, rec, desc);
      break;

    case REC_sync:
      SNetRecDestroy(rec);
      break;

    case REC_star_leader:
      land->star_leader = true;
      land->detenter.counter = LEADER_REC(rec, counter);
      land->detenter.seqnr   = LEADER_REC(rec, seqnr  );
      SNetRecDestroy(rec);
      break;

    default:
      SNetRecUnknownEnt(__func__, rec, sarg->entity);
  }
}
Example #2
0
File: star.c Project: jsyk/snet-rts
/**
 * Star component task
 */
static void StarBoxTask(void *arg)
{
  star_arg_t *sarg = arg;
  snet_record_t *rec;

  /* read from input stream */
  rec = SNetStreamRead( sarg->instream);

  switch( SNetRecGetDescriptor( rec)) {

    case REC_data:
      if( MatchesExitPattern( rec, sarg->exit_patterns, sarg->guards)) {
        assert(!sarg->sync_cleanup);
#ifdef DEBUG_PRINT_GC
        SNetUtilDebugNoticeEnt( ent,
            "[STAR] Notice: Data leaves replication network.");
#endif
        /* send rec to collector */
        SNetStreamWrite( sarg->outstream, rec);
      } else {
        /* if instance has not been created yet, create it */
        if( sarg->nextstream == NULL) {
          CreateOperandNetwork(&sarg->nextstream, sarg, sarg->outstream);
        }
        /* send the record to the instance */
        SNetStreamWrite( sarg->nextstream, rec);
      } /* end if not matches exit pattern */

      /* deterministic non-incarnate has to append control records */
      if (sarg->is_det && !sarg->is_incarnate) {
        /* send new sort record to collector level=0, counter=0*/
        SNetStreamWrite( sarg->outstream,
            SNetRecCreate( REC_sort_end, 0, sarg->counter) );

        /* if has next instance, send new sort record */
        if (sarg->nextstream != NULL) {
          SNetStreamWrite( sarg->nextstream,
              SNetRecCreate( REC_sort_end, 0, sarg->counter) );
        }
        /* increment counter */
        sarg->counter++;

      }
#ifdef ENABLE_GC
      else if (sarg->sync_cleanup) {
        snet_record_t *term_rec;
        /*
         * If sync_cleanup is set, we decided to postpone termination
         * due to garbage collection triggered by a sync record until now.
         * Postponing was done in order not to create the operand network unnecessarily
         * only to be able to forward the sync record.
         */
        assert( sarg->nextstream != NULL);
        /* first send a sync record to the next instance */
        SNetStreamWrite( sarg->nextstream,
            SNetRecCreate( REC_sync, SNetStreamGet(sarg->instream)) );


        /* send a terminate record to collector, it will close and
           destroy the stream */
        term_rec = SNetRecCreate(REC_terminate);
        SNetRecSetFlag(term_rec);
        SNetStreamWrite( sarg->outstream, term_rec);

#ifdef DEBUG_PRINT_GC
        /* terminating due to GC */
        SNetUtilDebugNoticeEnt( ent,
            "[STAR] Notice: Destroying star dispatcher due to GC, "
            "delayed until new data record!"
            );
#endif
        SNetStreamClose(sarg->nextstream, false);
        SNetStreamClose(sarg->instream, false);
        TerminateStarBoxTask(sarg->outstream,sarg);
        return;
      }
#endif /* ENABLE_GC */
      break;

    case REC_sync:
      {
        snet_stream_t *newstream = SNetRecGetStream( rec);
#ifdef ENABLE_GC
        snet_locvec_t *loc = SNetStreamGetSource( newstream);
#ifdef DEBUG_PRINT_GC
        if (loc != NULL) {
          int size = SNetLocvecPrintSize(loc) + 1;
          char srecloc[size];
          srecloc[size - 1] = '\0';
          SNetLocvecPrint(srecloc, loc);
          SNetUtilDebugNoticeTask(
                "[STAR] Notice: Received sync record with a stream with source %s.",
                srecloc
                );
        }
#endif
        /* TODO
         * It is not necessary to carry the whole location vector in the
         * next stream of a star-entity, only a flag. As a prerequisite,
         * non_incarnates must not clean themselves up!
         */
        /*
         * Only incarnates are eligible for cleanup!
         * check if the source (location) of the stream and the own location are
         * (subsequent) star dispatcher entities of the same star combinator network
         * -> if so, we can clean-up ourselves
         */
        if ( sarg->is_incarnate && loc != NULL ) {
          assert( true == SNetLocvecEqualParent(loc, SNetLocvecGet(sarg->info)) );
          /* If the next instance is already created, we can forward the sync-record
           * immediately and terminate.
           * Otherwise we postpone termination to the point when a next data record
           * is received, as we create the operand network then.
           */
          if (sarg->nextstream != NULL) {
            snet_record_t *term_rec;
            /* forward the sync record  */
            SNetStreamWrite( sarg->nextstream, rec);
            /* send a terminate record to collector, it will close and
               destroy the stream */
            term_rec = SNetRecCreate(REC_terminate);
            SNetRecSetFlag(term_rec);
            SNetStreamWrite( sarg->outstream, term_rec);

#ifdef DEBUG_PRINT_GC
            /* terminating due to GC */
            SNetUtilDebugNoticeEnt( ent,
                "[STAR] Notice: Destroying star dispatcher due to GC, "
                "immediately on sync!"
                );
#endif
            SNetStreamClose(sarg->nextstream, false);
            SNetStreamClose(sarg->instream, true);
            TerminateStarBoxTask(sarg->outstream,sarg);
            return;
          } else {
            sarg->sync_cleanup = true;
#ifdef DEBUG_PRINT_GC
            SNetUtilDebugNoticeEnt( ent,
                "[STAR] Notice: Remembering delayed destruction.");
#endif
            /* handle sync record as usual */
            SNetStreamReplace( sarg->instream, newstream);
            SNetRecDestroy( rec);
          }
        } else
#endif /* ENABLE_GC */
        {
          /* handle sync record as usual */
          SNetStreamReplace( sarg->instream, newstream);
          SNetRecDestroy( rec);
        }
      }
      break;


    case REC_sort_end:
      {
        int rec_lvl = SNetRecGetLevel(rec);
        /* send a copy to the box, if exists */
        if( sarg->nextstream != NULL) {
          SNetStreamWrite(
              sarg->nextstream,
              SNetRecCreate( REC_sort_end,
                (!sarg->is_incarnate)? rec_lvl+1 : rec_lvl,
                SNetRecGetNum(rec) )
              );
        }

        /* send the original one to the collector */
        if (!sarg->is_incarnate) {
          /* if non-incarnate, we have to increase level */
          SNetRecSetLevel( rec, rec_lvl+1);
        }
        SNetStreamWrite( sarg->outstream, rec);
      }
      break;

    case REC_terminate:
      if( sarg->nextstream != NULL) {
        SNetStreamWrite( sarg->nextstream, SNetRecCopy( rec));
        SNetStreamClose( sarg->nextstream, false);
      }
      SNetStreamWrite( sarg->outstream, rec);
      /* note that no sort record has to be appended */
      SNetStreamClose(sarg->instream, true);
      TerminateStarBoxTask(sarg->outstream,sarg);

      return;

    case REC_collect:
    default:
      SNetUtilDebugFatal("Unknown record type!");
      /* if ignore, at least destroy ... */
      SNetRecDestroy( rec);
  }
  SNetThreadingRespawn(NULL);
}