/* 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; }
/* Allocate a new stream */ snet_stream_t *SNetStreamCreate(int capacity) { snet_stream_t *stream; trace(__func__); stream = SNetNewAlign(snet_stream_t); STREAM_FROM(stream) = NULL; STREAM_DEST(stream) = NULL; return stream; }
/* 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); }
/* Open a descriptor to an output stream. * * The source landing which opens the stream is determined by parameter 'prev'. * The new descriptor holds a pointer to a landing which instantiates * the destination node as determined by the stream parameter 'stream'. * * Special cases: * (1) Dispatchers should create an additional landing for a future collector * and push this landing onto a stack of future landings. * (2) Collectors should retrieve their designated landing from this stack * and verify that it is theirs. */ snet_stream_desc_t *SNetStreamOpen( snet_stream_t *stream, snet_stream_desc_t *prev) { snet_stream_desc_t *desc; trace(__func__); desc = SNetNewAlign(snet_stream_desc_t); DESC_STREAM(desc) = stream; desc->source = prev->landing; desc->refs = 1; SNetFifoInit(&desc->fifo); switch (NODE_TYPE(stream->dest)) { case NODE_filter: case NODE_nameshift: case NODE_output: desc->landing = SNetNewLanding(DESC_DEST(desc), prev, LAND_siso); DESC_LAND_SPEC(desc, siso)->outdesc = NULL; break; case NODE_box: SNetNewBoxLanding(desc, prev); break; case NODE_parallel: SNetNewParallelLanding(desc, prev); break; case NODE_star: SNetNewStarLanding(desc, prev); break; case NODE_split: SNetNewSplitLanding(desc, prev); break; case NODE_feedback: SNetNewFeedbackLanding(desc, prev); break; case NODE_dripback: SNetNewDripBackLanding(desc, prev); break; case NODE_sync: desc->landing = SNetNewLanding(STREAM_DEST(stream), prev, LAND_sync); SNetSyncInitDesc(desc, stream); break; case NODE_zipper: /* Init the landing state of a fused sync-star node */ desc->landing = SNetNewLanding(STREAM_DEST(stream), prev, LAND_zipper); DESC_LAND_SPEC(desc, zipper)->outdesc = NULL; DESC_LAND_SPEC(desc, zipper)->head = NULL; break; case NODE_collector: /* Collectors receive the previously created landing from the stack */ desc->landing = SNetPopLanding(prev); assert(desc->landing); assert(desc->landing->type == LAND_collector); assert(DESC_NODE(desc) == STREAM_DEST(stream)); assert(desc->landing->refs > 0); break; case NODE_observer: desc->landing = SNetNewLanding(DESC_DEST(desc), prev, LAND_observer); DESC_LAND_SPEC(desc, observer)->outdesc = NULL; DESC_LAND_SPEC(desc, observer)->oid = 0; break; case NODE_observer2: desc->landing = SNetPopLanding(prev); assert(desc->landing); assert(desc->landing->type == LAND_empty); break; case NODE_input: case NODE_identity: case NODE_garbage: default: desc->landing = NULL; assert(0); break; } /* if (SNetVerbose() && SNetNodeGetWorkerCount() <= 1) { printf("%s: %s, %s\n", __func__, SNetNodeName(desc->landing->node), SNetLandingName(desc->landing)); } */ return desc; }