Beispiel #1
0
/* Read one record from the parser. */
input_state_t SNetGetNextInputRecord(landing_t *land)
{
  landing_input_t       *linp = LAND_SPEC(land, input);
  input_arg_t           *iarg = NODE_SPEC(land->node, input);
  snet_record_t         *record = NULL;

  trace(__func__);
  assert(NODE_TYPE(land->node) == NODE_input);

  if (iarg->state == INPUT_reading) {
    // Ask parser for a new input record.
    while (SNetInParserGetNextRecord(&record) == SNET_PARSE_CONTINUE) {
      if (record) {
        break;
      }
    }
    if (record) {
      if (REC_DESCR(record) == REC_terminate) {
        SNetRecDestroy(record);
        iarg->state = INPUT_terminating;
      } else {
        linp->num_inputs += 1;
        SNetWrite(&linp->outdesc, record, false);
        return INPUT_reading;
      }
    } else {
      iarg->state = INPUT_terminating;
    }
    return iarg->state;
  } else {
    return INPUT_terminated;
  }
}
Beispiel #2
0
/* Deallocate input node */
void SNetStopInput(node_t *node, fifo_t *fifo)
{
  input_arg_t   *iarg = NODE_SPEC(node, input);

  trace(__func__);
  iarg->indesc->landing->refs = 0;
  SNetFreeLanding(iarg->indesc->landing);
  SNetDelete(iarg->indesc);
  SNetStopStream(iarg->output, fifo);
  SNetDelete(node);
}
Beispiel #3
0
void SNetCloseInput(node_t* node)
{
  input_arg_t           *iarg = NODE_SPEC(node, input);
  landing_input_t       *linp = DESC_LAND_SPEC(iarg->indesc, input);

  trace(__func__);
  assert(iarg->state == INPUT_terminating);
  iarg->state = INPUT_terminated;
  SNetDescDone(linp->outdesc);
  SNetInParserDestroy();
}
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
static bool SNetInputAllowed(worker_t *worker)
{
  bool allowed = true;

  if (SNetInputThrottle()) {
    /* Check if output has advanced enough for us to input more. */
    size_t outs = NODE_SPEC(worker->output_node, output)->num_outputs;
    size_t ins = DESC_LAND_SPEC(worker->input_desc, input)->num_inputs;
    double limit = SNetInputOffset() + SNetInputFactor() * outs;
    allowed = (ins < limit);
  }

  return allowed;
}
Beispiel #6
0
/* Test if other workers have work to do. */
bool SNetWorkerOthersBusy(worker_t *worker)
{
  int   i;
  bool  change = false;

  if (worker->output_node) {
    if (NODE_SPEC(worker->output_node, output)->terminated) {
      return false;
    }
  }

  if (worker->is_idle < 1) {
    worker->idle_seqnr += 1;
    worker->is_idle = 1;
  }

  for (i = 1; i <= snet_worker_count; ++i) {
    worker_t *other = snet_workers[i];
    if (!other) {
      worker->is_idle = 1;
      change = true;
      break;
    }
    else if (other != worker) {
      if (other->is_idle == 0) {
        worker->is_idle = 1;
        change = true;
        break;
      }
      else if (worker->idle_seqnr < other->idle_seqnr) {
        worker->idle_seqnr = other->idle_seqnr;
        worker->is_idle = 1;
        change = true;
      }
      else if (worker->idle_seqnr > other->idle_seqnr) {
        worker->is_idle = 1;
        change = true;
      }
      else if (other->is_idle < worker->is_idle) {
        change = true;
      }
    }
  }
  if (change == false) {
    worker->is_idle += 1;
  }

  return (worker->is_idle < 3);
}
Beispiel #7
0
/* Create a new worker. */
worker_t *SNetWorkerCreate(
    node_t *input_node,
    int worker_id,
    node_t *output_node,
    worker_role_t role)
{
  worker_t *worker;

  trace(__func__);

  worker = SNetNewAlign(worker_t);
  worker->id = worker_id;
  worker->role = role;
  worker->victim_id = worker_id;

  WorkerTodoInit(&worker->todo);

  worker->prev = worker->iter = &worker->todo.head;

  WorkerFreeInit(&worker->free);

  if (input_node) {
    worker->input_desc = NODE_SPEC(input_node, input)->indesc;
    worker->has_input = true;
  } else {
    worker->input_desc = NULL;
    worker->has_input = false;
  }
  worker->output_node = output_node;
  worker->steal_lock = SNetNewAlign(worker_lock_t);
  worker->steal_lock->id = 0;
  worker->steal_turn = SNetNewAlign(worker_turn_t);
  worker->steal_turn->turn = 1;
  
  worker->loot.desc = NULL;
  worker->loot.count = 0;
  worker->loot.item = NULL;
  worker->hash_ptab = SNetHashPtrTabCreate(10, true);
  worker->continue_desc = NULL;
  worker->continue_rec = NULL;
  worker->has_work = true;
  worker->is_idle = false;
  worker->idle_seqnr = 0;

  return worker;
}
Beispiel #8
0
/* 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);
  }
}
Beispiel #9
0
/* 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);
  }
}
Beispiel #10
0
/* Create the node which reads records from an input file via the parser.
 * This is called from networkinterface.c to initialize the input module.
 */
void SNetInInputInit(
    FILE                *file,
    snetin_label_t      *labels,
    snetin_interface_t  *interfaces,
    snet_stream_t       *output)
{
  input_arg_t           *iarg;
  node_t                *node;
  landing_input_t       *linp;
  const int              first_worker_id = 1;
  
  trace(__func__);

  /* Create input node in the fixed network. */
  node = SNetNodeNew(NODE_input, (snet_stream_t **)NULL, 0, &output, 1,
                     SNetNodeInput, SNetStopInput, SNetTermInput);
  iarg = NODE_SPEC(node, input);
  iarg->output = output;
  iarg->state = INPUT_reading;

  /* Create an empty input descriptor: needed for SNetStreamOpen. */
  iarg->indesc = SNetNewAlign(snet_stream_desc_t);
  memset(iarg->indesc, 0, sizeof(snet_stream_desc_t));

  /* Create landing: needed for locking the input node before use. */
  iarg->indesc->landing = SNetNewLanding(node, NULL, LAND_input);
  linp = DESC_LAND_SPEC(iarg->indesc, input);
  linp->num_inputs = 0;

  /* Create output descriptor: needed by parser for writing. */
  iarg->indesc->landing->id = first_worker_id;
  linp->outdesc = SNetStreamOpen(output, iarg->indesc);
  iarg->indesc->landing->id = 0;

  /* Initialize the parser */
  SNetInParserInit(file, labels, interfaces, NULL, NULL);
}
Beispiel #11
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 #12
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;
}