Beispiel #1
0
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");
}
Beispiel #2
0
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");
}
Beispiel #3
0
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!?
}
Beispiel #4
0
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);
  }
}
Beispiel #5
0
Buffer* OperationItemSupplier::getBuffer() const
{
  return getFlows().begin()->getBuffer();
}