Exemplo n.º 1
0
/**
 * Peeks the top record of all streams in waitingset,
 * if there is a terminate record, the stream is closed
 * and removed from the waitingset
 */
static int DestroyTermInWaitingSet(snet_stream_iter_t *wait_iter,
    snet_streamset_t *waitingset)
{
  int destroy_cnt=0;
  if ( !SNetStreamsetIsEmpty( waitingset)) {
    SNetStreamIterReset( wait_iter, waitingset);
    while( SNetStreamIterHasNext( wait_iter)) {
      snet_stream_desc_t *sd = SNetStreamIterNext( wait_iter);
      snet_record_t *wait_rec = SNetStreamPeek( sd);

      /* for this stream, check if there is a termination record next */
      if ( wait_rec != NULL &&
          SNetRecGetDescriptor( wait_rec) == REC_terminate ) {
        /* consume, remove from waiting set and free the stream */
        (void) SNetStreamRead( sd);
        SNetStreamIterRemove( wait_iter);
        SNetStreamClose( sd, true);
        /* update destroyed counter */
        destroy_cnt++;
        /* destroy record */
        SNetRecDestroy( wait_rec);
      }
      /* else do nothing */
    }
  }
  return destroy_cnt;
}
Exemplo n.º 2
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 */
Exemplo n.º 3
0
snet_stream_desc_t *SNetStreamPoll(snet_streamset_t *set)
{
  assert( *set != NULL);

  snet_stream_desc_t *result = NULL;
  /* get 'self', i.e. the task calling SNetStreamPoll()
   * the set is a simple pointer to the last element
   */
  snet_thread_t *self = SNetThreadingSelf();
  snet_stream_iter_t *iter;
  int cnt = 0;

  //self = (*set)->thr;

  iter = SNetStreamIterCreate(set);

  /* fast path: there is something anywhere */
  {
    while( SNetStreamIterHasNext(iter)) {
      snet_stream_desc_t *sd = SNetStreamIterNext( iter);
      snet_stream_t *s = sd->stream;
      pthread_mutex_lock(&s->lock);
      if (s->count > 0) result = sd;
      pthread_mutex_unlock(&s->lock);
    }
    if (result != NULL) {
      goto poll_fastpath;
    }
  }




  /* reset wakeup_sd */
  pthread_mutex_lock( &self->lock );
  self->wakeup_sd = NULL;
  pthread_mutex_unlock( &self->lock );

  /* for each stream in the set */
  SNetStreamIterReset(iter, set);
  while( SNetStreamIterHasNext(iter)) {
    snet_stream_desc_t *sd = SNetStreamIterNext( iter);
    snet_stream_t *s = sd->stream;

    /* lock stream (prod-side) */
    pthread_mutex_lock( &s->lock);
    { /* CS BEGIN */
      /* check if there is something in the buffer */
      if ( s->count > 0 ) {
        /* yes, we can stop iterating through streams. */
        pthread_mutex_lock( &self->lock );
        if (self->wakeup_sd == NULL) {
          self->wakeup_sd = sd;
        }
        /* unlock self */
        pthread_mutex_unlock( &self->lock );
        /* unlock stream */
        pthread_mutex_unlock( &s->lock);
        /* exit loop */
        break;

      } else {
        /* nothing in the buffer, register stream as activator */
        s->is_poll = 1;
        cnt++;
      }
    } /* CS END */
    /* unlock stream */
    pthread_mutex_unlock( &s->lock);
  } /* end for each stream */

  /* wait until wakeup_sd is set */
  pthread_mutex_lock( &self->lock );
  while( self->wakeup_sd == NULL ) {
    pthread_cond_wait(&self->pollcond, &self->lock);
  }
  result = self->wakeup_sd;
  self->wakeup_sd = NULL;
  pthread_mutex_unlock( &self->lock );

  SNetStreamIterReset(iter, set);
  while( SNetStreamIterHasNext(iter)) {
    snet_stream_t *s = (SNetStreamIterNext(iter))->stream;
    pthread_mutex_lock(&s->lock);
    s->is_poll = 0;
    pthread_mutex_unlock(&s->lock);
    if (--cnt == 0) break;
  }

poll_fastpath:
  SNetStreamIterDestroy(iter);
  /* 'rotate' list to stream descriptor for non-empty buffer */
  *set = result;

  return result;
}