DECLARE_EXPORT Buffer* OperationItemDistribution::getDestination() const { for (flowlist::const_iterator i = getFlows().begin(); i != getFlows().end(); ++i) if (i->getQuantity() > 0.0) return i->getBuffer(); throw LogicException("Transfer operation doesn't produce material"); }
Buffer* OperationItemDistribution::getOrigin() const { for (flowlist::const_iterator i = getFlows().begin(); i != getFlows().end(); ++i) if (i->getQuantity() < 0.0) return i->getBuffer(); throw LogicException("Transfer operation doesn't consume material"); }
int main(int argc, char *argv[]) { int i; // Keep track of when the simulation starts gettimeofday(&startTime, NULL); if(argc != 2) { fprintf(stderr, "Usage: MFS <input file>\n"); return -1; } // Parse input file, put all flows into allFlows, initialize remainingFlows getFlows(argv[1]); // Create the queue for the threads to wait in. Set the default queue values to an empty flow, i.e., flowNumber = 0. flowQueue = malloc(numberOfFlows * sizeof(flowPointer)); flow emptyFlow; emptyFlow.flowNumber = 0; for (i = 0; i < numberOfFlows; i ++) { flowQueue[i] = &emptyFlow; } // Initialize the currentlyTransmittingFlow to the emptyFlow because there are no flows tranmsitting yet. currentlyTransmittingFlow = &emptyFlow; // Start scheduler thread pthread_t schedulerThreadId; pthread_create(&schedulerThreadId, NULL, schedulerFunction, NULL); // Create all the threads for (i = 0; i < numberOfFlows; i ++) { pthread_create(&(allFlows[i]->threadId), NULL, flowFunction, allFlows[i]); } pthread_mutex_lock(&remainingFlowsMutex); // Tell the scheduler to begin printf("MAIN: Telling Scheduler to begin!\n"); pthread_cond_signal(&nobodyTransmittingCondVar); pthread_mutex_unlock(&remainingFlowsMutex); // Wait for all threads to finish for (i = 0; i < numberOfFlows; i ++) { pthread_join(allFlows[i]->threadId, NULL); } pthread_join(schedulerThreadId, NULL); free(allFlows); free(flowQueue); return 0; // Success!? }
void OperationItemSupplier::trimExcess(bool zero_or_minimum) const { // This method can only trim operations not loading a resource if (getLoads().begin() != getLoads().end()) return; for (Operation::flowlist::const_iterator fliter = getFlows().begin(); fliter != getFlows().end(); ++fliter) { if (fliter->getQuantity() <= 0) // Strange, shouldn't really happen continue; FlowPlan* candidate = nullptr; double curmin = 0; double oh = 0; double excess_min = DBL_MAX; for (Buffer::flowplanlist::const_iterator flplniter = fliter->getBuffer()->getFlowPlans().begin(); flplniter != fliter->getBuffer()->getFlowPlans().end(); ++flplniter) { // For any operationplan we get the onhand when its successor // replenishment arrives. If that onhand is higher than the minimum // onhand value we can resize it. // This is only valid in unconstrained plans and when there are // no upstream activities. if (flplniter->getEventType() == 3 && zero_or_minimum) curmin = flplniter->getMin(); else if (flplniter->getEventType() == 1) { const FlowPlan* flpln = static_cast<const FlowPlan*>(&*flplniter); if (oh - curmin < excess_min) { excess_min = oh - curmin; if (excess_min < 0) excess_min = 0; } if (flpln->getQuantity() > 0 && !flpln->getOperationPlan()->getLocked() && (!candidate || candidate->getDate() != flpln->getDate())) { if (candidate && excess_min > ROUNDING_ERROR && candidate->getQuantity() > excess_min + ROUNDING_ERROR && candidate->getQuantity() > getSizeMinimum() + ROUNDING_ERROR ) { // This candidate can now be resized candidate->setQuantity(candidate->getQuantity() - excess_min, false); candidate = nullptr; } else if (flpln->getOperation() == this) candidate = const_cast<FlowPlan*>(flpln); else candidate = nullptr; excess_min = DBL_MAX; } } oh = flplniter->getOnhand(); } if (candidate && excess_min > ROUNDING_ERROR && candidate->getQuantity() > excess_min + ROUNDING_ERROR && candidate->getQuantity() > getSizeMinimum() + ROUNDING_ERROR ) // Resize the last candidate at the end of the horizon candidate->setQuantity(candidate->getQuantity() - excess_min, false); } }
Buffer* OperationItemSupplier::getBuffer() const { return getFlows().begin()->getBuffer(); }