예제 #1
0
 @Override
 public void run() {
   int counter;
   System.out.printf(
       "%s: Processing lines from %d to %d\n",
       Thread.currentThread().getName(), firstRow, lastRow);
   for (int i = firstRow; i < lastRow; i++) {
     int row[] = mock.getRow(i);
     counter = 0;
     for (int j = 0; j < row.length; j++) {
       if (row[j] == number) {
         counter++;
       }
     }
     results.setData(i, counter);
     try {
       Thread.sleep(10);
     } catch (InterruptedException e) {
       // TODO: handle exception
     }
   }
   System.out.printf("%s: Lines processed \n", Thread.currentThread().getName());
   try {
     barrier.await();
   } catch (InterruptedException e) {
     e.printStackTrace();
   } catch (BrokenBarrierException e) {
     e.printStackTrace();
   }
 }
  /** This is run before each @TestD method. */
  @Before
  public void before() {
    if (!run) {
      AutowireCapableBeanFactory beanFactory = applicationContext.getAutowireCapableBeanFactory();
      bot =
          (MyBot)
              beanFactory.autowire(MyBot.class, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false);
      Object botBean = beanFactory.initializeBean(bot, "mybot");
      bot = (MyBot) botBean;
      // the bot also needs a trigger so its act() method is called regularly.
      // (there is no trigger bean in the context)
      PeriodicTrigger trigger = new PeriodicTrigger(ACT_LOOP_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
      trigger.setInitialDelay(ACT_LOOP_INITIAL_DELAY_MILLIS);
      bot.setTrigger(trigger);
      logger.info("starting test case testGroupBot");
      // adding the bot to the bot manager will cause it to be initialized.
      // at that point, the trigger starts.
      botManager.addBot(bot);

      // the bot should now be running. We have to wait for it to finish before we
      // can check the results:
      // Together with the barrier.await() in the bot's listener, this trips the barrier
      // and both threads continue.
      try {
        bot.getBarrier().await();
      } catch (InterruptedException e) {
        e.printStackTrace(); // To change body of catch statement use File | Settings | File
        // Templates.
      } catch (BrokenBarrierException e) {
        e.printStackTrace(); // To change body of catch statement use File | Settings | File
        // Templates.
      }
      run = true;
    }
  }
예제 #3
0
  public void run() {
    try {
      Thread.sleep(1000);
      System.out.println(Thread.currentThread().getName() + " waiting at barrier 1");
      /*
       * 阻塞等待条件1达成
       */
      this.barrier1.await();
      Thread.sleep(1000);
      System.out.println(Thread.currentThread().getName() + " waiting at barrier 2");
      /*
       * 阻塞等待条件2达成
       */
      this.barrier2.await();
      System.out.println(Thread.currentThread().getName() + " waiting at barrier 3");

      this.barrier3.await();
      Thread.sleep(1000);
      System.out.println(Thread.currentThread().getName() + " done!");

    } catch (InterruptedException e) {
      e.printStackTrace();
    } catch (BrokenBarrierException e) {
      e.printStackTrace();
    }
  }
    @Override
    public void run() {

      while (true) {
        if (curQue.get() < 0) {
          if (isTraceEnabled) {
            logger.trace("Thread {} is leaving traversing job.", Thread.currentThread().getName());
          }
          break;
        }
        int curQueTemp = curQue.get();
        VectorClock G = ques[curQueTemp].poll();
        try {
          if (G == null) {
            barrier.await();
            if (isTraceEnabled) {
              logger.trace(
                  "Thread {} is leaving the barrier and curQue = {}.",
                  Thread.currentThread().getName(),
                  curQueTemp);
            }
            continue;
          }
        } catch (InterruptedException e) {
          logger.warn(
              "Thread in the barrier is interrupted: {}", Arrays.toString(e.getStackTrace()));
          break;
        } catch (BrokenBarrierException e) {
          logger.warn(
              "The barrier in {} is broken: {}",
              ConcurrentBFSTraverser.class,
              Arrays.toString(e.getStackTrace()));
          break;
        }

        enumerator.enumerate(poset, G); // evaluate predicate

        for (int i = 0; i < n; ++i) {
          if (!poset.isNextEnabled(G, i)) continue;
          boolean hasDuplicate = false;
          for (int j = 0; j < n; ++j) {
            if (i == j) continue;
            if (poset
                .getVectorClock(i, G.get(i) + 1)
                .isConcurrentWith(poset.getVectorClock(j, G.get(j)))) {
              if (poset.getId(i, G.get(i) + 1) < poset.getId(j, G.get(j))) hasDuplicate = true;
            }
          }
          if (!hasDuplicate) {
            VectorClock H = VectorClock.copyOf(G);
            H.set(i, G.get(i) + 1);
            if (isTraceEnabled) logger.trace("Adding a frontier to next level of que.");
            ques[1 - curQueTemp].add(H);
          }
        }
      }
      enumerator.close();
    }
예제 #5
0
 public void finalBarrier() {
   try {
     finalBarrier.await();
   } catch (InterruptedException e) {
     return;
   } catch (BrokenBarrierException e) {
     throw new OMPRuntimeException(e.getMessage());
   }
 }
예제 #6
0
 private static boolean waitBarrier(CyclicBarrier barrier) {
   while (true)
     try {
       barrier.await();
       return true;
     } catch (InterruptedException ex) {
       continue;
     } catch (BrokenBarrierException ex) {
       ex.printStackTrace();
       return false;
     }
 }
 public void run() {
   System.out.println("[并发任务" + name + "]  开始执行");
   for (int i = 0; i < 999999; i++) ; // 模拟耗时的任务
   System.out.println("[并发任务" + name + "]  开始执行完毕,通知障碍器");
   try {
     // 每执行完一项任务就通知障碍器
     cb.await();
   } catch (InterruptedException e) {
     e.printStackTrace();
   } catch (BrokenBarrierException e) {
     e.printStackTrace();
   }
 }
예제 #8
0
    public void run() {
      try {
        System.out.println(Thread.currentThread().getName() + " wait for CyclicBarrier.");

        // 将cb的参与者数量加1
        cb.await();

        // cb的参与者数量等于5时,才继续往后执行
        System.out.println(Thread.currentThread().getName() + " continued.");
      } catch (BrokenBarrierException e) {
        e.printStackTrace();
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  private int await() {
    if (skipBarrier) {
      log.warn("Skipping barriers.....");
      return configuration.getNodesNum();
    }

    int parties = -1;
    try {
      parties = barrier.await();
    } catch (InterruptedException e) {
      e.printStackTrace();
    } catch (BrokenBarrierException e) {
      e.printStackTrace();
    }
    return parties;
  }
    @Override
    public StartContainersResponse startContainers(StartContainersRequest request)
        throws IOException {
      try {
        startLaunchBarrier.await();
        completeLaunchBarrier.await();
        // To ensure the kill is started before the launch
        Thread.sleep(100);
      } catch (InterruptedException e) {
        e.printStackTrace();
      } catch (BrokenBarrierException e) {
        e.printStackTrace();
      }

      throw new IOException(new ContainerException("Force fail CM"));
    }
    @Override
    public void run() {
      try {
        barrier.await();
      } catch (InterruptedException e) {
        e.printStackTrace();
        return;
      } catch (BrokenBarrierException e) {
        e.printStackTrace();
        return;
      }

      for (int i = 1; i <= readerIterations; i++) {
        iterate();
      }
    }
예제 #12
0
    @Override
    public void run() {
      System.out.println(Thread.currentThread().getName() + "开始计算...");

      try {
        Thread.sleep(2000);
        numbers[index] = index;
        System.out.println(Thread.currentThread().getName() + "完成计算...");
        cyclicBarrier.await(2, TimeUnit.SECONDS);

      } catch (InterruptedException e) {
        e.printStackTrace();
      } catch (BrokenBarrierException e) {
        e.printStackTrace();
      } catch (TimeoutException e) {
        e.printStackTrace();
      }

      System.out.println("所有线程都已完成计算,开始汇总...");
    }
  public void run() {
    if (!isEventHandled()) {
      synchronized (this) {
        try {
          wait(timeout_);
        } catch (InterruptedException e) {
          // ignored
        }
      }
    }

    if (barrier_ != null) {
      try {
        barrier_.await();
      } catch (InterruptedException ie) {
        // ignored
      } catch (BrokenBarrierException e) {
        e.printStackTrace();
      }
    }
  }
예제 #14
0
    @Override
    public void run() {
      try {
        TimeUnit.SECONDS.sleep(new Random().nextInt(10));
      } catch (InterruptedException e) {
        // TODO 自动生成的 catch 块
        e.printStackTrace();
      }

      System.out.println(Thread.currentThread().getName() + " is ready to action");
      try {
        barrier.await();

        System.out.println(Thread.currentThread().getName() + " start ...");
      } catch (InterruptedException e) {
        // TODO 自动生成的 catch 块
        e.printStackTrace();
      } catch (BrokenBarrierException e) {
        // TODO 自动生成的 catch 块
        e.printStackTrace();
      }
    }
예제 #15
0
  /**
   * _step Do the step for a single thread
   *
   * @param time
   * @param timeDelta
   * @param cycle
   * @param threadnum
   */
  protected void _step(STEMTime time, long timeDelta, int cycle, short threadnum) {
    //		this.setProgress(0.0);
    // We only deal with standard disease model decorators

    ArrayList<Decorator> iDecorators = new ArrayList<Decorator>();

    for (Decorator d : getDecorators()) {
      if (d instanceof IntegrationDecorator) iDecorators.add(d);
    }

    // First we get the step size, either the default step size
    // (initially 1.0) or the last step size used.

    double h = this.getStepSize();
    // x is to keep track of how far we have advanced in the solution. It is essentially
    // a double cycle representation

    double x = this.getCurrentX();

    // Substantial performance can be gained here. Basically if the current cycle
    // is greater than the cycle requested by the simulation, we are done. This
    // means that the error tolerance between last step and this step is small
    // enough so we don't need to update the labels. The error tolerance is
    // specified in the disease model

    // *** OBSERVE: Since we limit h to max 1 below, this code is never invoked. It's kept
    // *** around in case we want to allow time to be calculated far out in the future if
    // *** the error is small enough

    if (x >= cycle) {
      // Just copy the next value the same as the current value for all labels
      for (Decorator sdm : iDecorators) {
        EList<DynamicLabel> myLabels = sdm.getLabelsToUpdate(threadnum, num_threads);
        int numLabels = myLabels.size();
        double n = 0.0;
        int setProgressEveryNthNode = num_threads * numLabels / (MAX_PROGRESS_REPORTS);
        if (setProgressEveryNthNode == 0) setProgressEveryNthNode = 1;
        for (final Iterator<DynamicLabel> currentStateLabelIter = myLabels.iterator();
            currentStateLabelIter.hasNext(); ) {
          final IntegrationLabel diseaseLabel = (IntegrationLabel) currentStateLabelIter.next();

          // The estimated disease value contains the value calculated at position x

          IntegrationLabelValue nextValueAtX =
              (IntegrationLabelValue) EcoreUtil.copy(diseaseLabel.getProbeValue());
          IntegrationLabelValue currentValueAtCycle =
              (IntegrationLabelValue) diseaseLabel.getCurrentValue();
          IntegrationLabelValue nextState = (IntegrationLabelValue) diseaseLabel.getNextValue();
          adjustValuesToCycle(currentValueAtCycle, nextValueAtX, x, cycle);
          // NextValueAtX has been modified here to the correct value for this cycle.
          nextState.set(nextValueAtX);
          // The next value is valid now.
          diseaseLabel.setNextValueValid(true);
          double progress = n / numLabels;
          jobs[threadnum].setProgress(progress);
          if (n % setProgressEveryNthNode == 0) {
            // Get the progress for all threads
            for (int i = 0; i < num_threads; ++i)
              if (i != threadnum && jobs[i] != null) progress += jobs[i].getProgress();
            progress /= num_threads;
            sdm.setProgress(progress);
          }
          n += 1.0;
        }
      } // For each decorator
      // So that validation code above is happy
      jobs[threadnum].h = h;
      jobs[threadnum].t = x;

      return;
    }

    // When x (or time) is this we're done
    double end = Math.floor(this.getCurrentX()) + 1.0;

    // Make sure we actually have labels to update
    boolean workToDo = false;
    for (Decorator sdm : iDecorators)
      if (sdm.getLabelsToUpdate(threadnum, num_threads).size() > 0) {
        workToDo = true;
        break;
      }

    if (!workToDo) {
      // Nothing to do, just advance x and set h
      jobs[threadnum].h = h;
      jobs[threadnum].t = x;
      // Be nice and walk in step with others until done
      while (x < end) {
        try {
          // Set to a large number to make sure it's larger than any step size reported
          // by another thread
          do {
            jobs[threadnum].h = Double.MAX_VALUE;
            stepSizeBarrier.await();
          } while (this.maximumError > 1.0);
          updateDoneBarrier.await();
        } catch (InterruptedException ie) {
          // Should never happen
          Activator.logError(ie.getMessage(), ie);
        } catch (BrokenBarrierException bbe) {
          // Should never happen
          Activator.logError(bbe.getMessage(), bbe);
        }
        // Set to the smallest value reported by another thread
        h = this.smallestH;
        x += h;
        jobs[threadnum].h = h;
        jobs[threadnum].t = x;
      }
      return;
    }
    // We use the Runge Kutta Kash Carp method to advance to the next
    // step in the simulation. Two estimates of the disease deltas
    // are calculated and compared to each other. If they differ
    // by more than a maximum error (determined by a parameter for
    // the disease model), we reduce the step size until an acceptable
    // error is reached.

    // These are used during Runge Kutta calculations:
    Map<IntegrationLabel, IntegrationLabelValue> k1map =
        new HashMap<IntegrationLabel, IntegrationLabelValue>();
    Map<IntegrationLabel, IntegrationLabelValue> k2map =
        new HashMap<IntegrationLabel, IntegrationLabelValue>();
    Map<IntegrationLabel, IntegrationLabelValue> k3map =
        new HashMap<IntegrationLabel, IntegrationLabelValue>();
    Map<IntegrationLabel, IntegrationLabelValue> k4map =
        new HashMap<IntegrationLabel, IntegrationLabelValue>();
    Map<IntegrationLabel, IntegrationLabelValue> k5map =
        new HashMap<IntegrationLabel, IntegrationLabelValue>();
    Map<IntegrationLabel, IntegrationLabelValue> k6map =
        new HashMap<IntegrationLabel, IntegrationLabelValue>();

    // Used below as temporary place holder, one for each decorator
    IntegrationLabelValue _k1[], _k2[], _k3[], _k4[], _k5[], _k6[];
    int numDecorators = iDecorators.size();
    _k1 = new IntegrationLabelValue[numDecorators];
    _k2 = new IntegrationLabelValue[numDecorators];
    _k3 = new IntegrationLabelValue[numDecorators];
    _k4 = new IntegrationLabelValue[numDecorators];
    _k5 = new IntegrationLabelValue[numDecorators];
    _k6 = new IntegrationLabelValue[numDecorators];

    // The final estimates for label values are stored here
    Map<IntegrationLabel, IntegrationLabelValue> finalEstimate =
        new HashMap<IntegrationLabel, IntegrationLabelValue>();

    // Delta is used to scale the step (h)
    double delta = 0.0;

    int n = 0;
    for (Decorator sdm : iDecorators) {
      Iterator<DynamicLabel> iter = sdm.getLabelsToUpdate(threadnum, num_threads).iterator();
      IntegrationLabel firstLabel = (IntegrationLabel) iter.next();
      // Initialize temporary place holders just by creating dups of the first label available
      _k1[n] = (IntegrationLabelValue) EcoreUtil.copy(firstLabel.getCurrentValue());
      _k2[n] = (IntegrationLabelValue) EcoreUtil.copy(firstLabel.getCurrentValue());
      _k3[n] = (IntegrationLabelValue) EcoreUtil.copy(firstLabel.getCurrentValue());
      _k4[n] = (IntegrationLabelValue) EcoreUtil.copy(firstLabel.getCurrentValue());
      _k5[n] = (IntegrationLabelValue) EcoreUtil.copy(firstLabel.getCurrentValue());
      _k6[n++] = (IntegrationLabelValue) EcoreUtil.copy(firstLabel.getCurrentValue());
    }

    // Keep track if whether anyone want to stop
    // or pause updating labels
    boolean interrupt = false, pause = false;

    // We keep these around to determine when to call setProgress(...) on the decorators.
    // If we call too frequently we can too many callbacks which affects performance.
    double nextProgressReportStep = num_threads * (end - x) / MAX_PROGRESS_REPORTS;
    double nextProgressReport = x + nextProgressReportStep;

    //		HashMap<StandardDiseaseModelLabel, StandardDiseaseModelLabelValue> validate = new
    //			HashMap<StandardDiseaseModelLabel, StandardDiseaseModelLabelValue>();

    // This is the main loop we keep iterating over until we are done with the step
    while (x < end) {
      k1map.clear();
      k2map.clear();
      k3map.clear();
      k4map.clear();
      k5map.clear();
      k6map.clear();
      finalEstimate.clear();

      // Validation code kept here if needed in the future

      /*

        HashMap<StandardDiseaseModelLabel, StandardDiseaseModelLabelValue> validate = new HashMap<StandardDiseaseModelLabel, StandardDiseaseModelLabelValue>();


      if(!redo)
      	for(StandardDiseaseModelImpl sdm:diseaseModelDecorators) {
      		for (final Iterator<DynamicLabel> currentStateLabelIter = sdm.getLabelsToUpdate(threadnum, num_threads)
      			.iterator(); currentStateLabelIter.hasNext();) {
      			final StandardDiseaseModelLabel diseaseLabel = (StandardDiseaseModelLabel) currentStateLabelIter
      			.next();
      			final StandardDiseaseModelLabelValue val = (StandardDiseaseModelLabelValue)diseaseLabel.getCurrentDiseaseModelTempLabelValue();
      			validate.put(diseaseLabel, val);
      		}
      	}
      else {
      	for(StandardDiseaseModelImpl sdm:diseaseModelDecorators)
      		for (final Iterator<DynamicLabel> currentStateLabelIter = sdm.getLabelsToUpdate(threadnum, num_threads)
      				.iterator(); currentStateLabelIter.hasNext();) {
      				final StandardDiseaseModelLabel diseaseLabel = (StandardDiseaseModelLabel) currentStateLabelIter
      				.next();
      				final SIRLabelValue val = (SIRLabelValue)diseaseLabel.getCurrentDiseaseModelTempLabelValue();
      				validate.put(diseaseLabel, val);
      				final SIRLabelValue oldVal = (SIRLabelValue)validate.get(diseaseLabel);

      				if(val.getI() != oldVal.getI() ||
      						val.getS() != oldVal.getS() ||
      						val.getR() != oldVal.getR() ||
      						//val.getE() != oldVal.getE() ||
      						val.getBirths() != oldVal.getBirths() ||
      						val.getDeaths() != oldVal.getDeaths() ||
      						val.getDiseaseDeaths() != oldVal.getDiseaseDeaths()
      						)
      					Activator.logError("Error, old and new value not the same  label: "+diseaseLabel, new Exception());
      		}
      }
      */

      // ToDo: We should check if a maximum number of iterations have been
      // exceeded here and throw an error.

      // First, get the delta values at the current state
      for (Decorator sdm : iDecorators)
        ((IntegrationDecorator) sdm)
            .calculateDelta(time, timeDelta, sdm.getLabelsToUpdate(threadnum, num_threads));
      for (Decorator sdm : iDecorators)
        ((IntegrationDecorator) sdm)
            .applyExternalDeltas(time, timeDelta, sdm.getLabelsToUpdate(threadnum, num_threads));

      // Set the scaling factor for disease parameters for each decorator and location
      for (Decorator sdm : iDecorators) {
        for (final Iterator<DynamicLabel> currentStateLabelIter =
                sdm.getLabelsToUpdate(threadnum, num_threads).iterator();
            currentStateLabelIter.hasNext(); ) {
          final IntegrationLabel diseaseLabel = (IntegrationLabel) currentStateLabelIter.next();

          IntegrationLabelValue scale = (IntegrationLabelValue) diseaseLabel.getErrorScale();
          scale.set((IntegrationLabelValue) diseaseLabel.getTempValue());

          IntegrationLabelValue dt =
              (IntegrationLabelValue) EcoreUtil.copy(diseaseLabel.getDeltaValue());
          dt.scale(h);
          dt.abs();
          dt.add(TINY);
          scale.abs();
          scale.add(dt);
        }
      }

      // Step 1 in Runge Kutta Fehlberg.
      // Get the delta values out of each node label and
      // build a first estimate of the next value'
      for (Decorator sdm : iDecorators) {
        for (final Iterator<DynamicLabel> currentStateLabelIter =
                sdm.getLabelsToUpdate(threadnum, num_threads).iterator();
            currentStateLabelIter.hasNext(); ) {
          final IntegrationLabel diseaseLabel = (IntegrationLabel) currentStateLabelIter.next();

          IntegrationLabelValue deltaLabel = (IntegrationLabelValue) diseaseLabel.getDeltaValue();
          k1map.put(diseaseLabel, (IntegrationLabelValue) EcoreUtil.copy(deltaLabel));

          deltaLabel.scale(h);
          deltaLabel.scale(b21);
          ((IntegrationLabelValue) diseaseLabel.getProbeValue())
              .set(deltaLabel.add((IntegrationLabelValue) diseaseLabel.getTempValue()));
        }
      }

      // Now get the next delta values
      for (Decorator sdm : iDecorators)
        ((IntegrationDecorator) sdm)
            .calculateDelta(time, timeDelta, sdm.getLabelsToUpdate(threadnum, num_threads));
      for (Decorator sdm : iDecorators)
        ((IntegrationDecorator) sdm)
            .applyExternalDeltas(time, timeDelta, sdm.getLabelsToUpdate(threadnum, num_threads));

      // Step 2 in Runge Kutta Fehlberg.
      // Get the delta values out of each node label and
      // build a second estimate of the next value
      n = 0;
      for (Decorator sdm : iDecorators) {
        for (final Iterator<DynamicLabel> currentStateLabelIter =
                sdm.getLabelsToUpdate(threadnum, num_threads).iterator();
            currentStateLabelIter.hasNext(); ) {
          final IntegrationLabel diseaseLabel = (IntegrationLabel) currentStateLabelIter.next();

          IntegrationLabelValue deltaLabel = (IntegrationLabelValue) diseaseLabel.getDeltaValue();
          k2map.put(diseaseLabel, (IntegrationLabelValue) EcoreUtil.copy(deltaLabel));
          _k1[n].set(k1map.get(diseaseLabel));
          _k2[n].set(deltaLabel);

          IntegrationLabelValue estDelta = _k1[n].scale(b31);
          _k2[n].scale(b32);
          estDelta.add(_k2[n]);

          estDelta.scale(h);

          ((IntegrationLabelValue) diseaseLabel.getProbeValue())
              .set(estDelta.add((IntegrationLabelValue) diseaseLabel.getTempValue()));
        }
        ++n;
      }

      // Now get the next delta values
      for (Decorator sdm : iDecorators)
        ((IntegrationDecorator) sdm)
            .calculateDelta(time, timeDelta, sdm.getLabelsToUpdate(threadnum, num_threads));
      for (Decorator sdm : iDecorators)
        ((IntegrationDecorator) sdm)
            .applyExternalDeltas(time, timeDelta, sdm.getLabelsToUpdate(threadnum, num_threads));

      // Step 3 in Runge Kutta Fehlberg.
      // Get the delta values out of each node label and
      // build a third estimate of the next value
      n = 0;
      for (Decorator sdm : iDecorators) {
        for (final Iterator<DynamicLabel> currentStateLabelIter =
                sdm.getLabelsToUpdate(threadnum, num_threads).iterator();
            currentStateLabelIter.hasNext(); ) {
          final IntegrationLabel diseaseLabel = (IntegrationLabel) currentStateLabelIter.next();

          IntegrationLabelValue deltaLabel = (IntegrationLabelValue) diseaseLabel.getDeltaValue();
          k3map.put(diseaseLabel, (IntegrationLabelValue) EcoreUtil.copy(deltaLabel));

          _k1[n].set(k1map.get(diseaseLabel));
          _k2[n].set(k2map.get(diseaseLabel));
          _k3[n].set(deltaLabel);

          _k1[n].scale(b41);
          _k2[n].scale(b42);
          _k3[n].scale(b43);
          IntegrationLabelValue estDelta = _k1[n];
          estDelta.add(_k2[n]);
          estDelta.add(_k3[n]);

          estDelta.scale(h);

          ((IntegrationLabelValue) diseaseLabel.getProbeValue())
              .set(estDelta.add((IntegrationLabelValue) diseaseLabel.getTempValue()));
        }
        ++n;
      }

      // Now get the next delta values
      for (Decorator sdm : iDecorators)
        ((IntegrationDecorator) sdm)
            .calculateDelta(time, timeDelta, sdm.getLabelsToUpdate(threadnum, num_threads));
      for (Decorator sdm : iDecorators)
        ((IntegrationDecorator) sdm)
            .applyExternalDeltas(time, timeDelta, sdm.getLabelsToUpdate(threadnum, num_threads));

      // Step 4 in Runge Kutta Fehlberg.
      // Get the delta values out of each node label and
      // build a fourth estimate of the next value
      n = 0;
      for (Decorator sdm : iDecorators) {
        for (final Iterator<DynamicLabel> currentStateLabelIter =
                sdm.getLabelsToUpdate(threadnum, num_threads).iterator();
            currentStateLabelIter.hasNext(); ) {
          final IntegrationLabel diseaseLabel = (IntegrationLabel) currentStateLabelIter.next();

          IntegrationLabelValue deltaLabel = (IntegrationLabelValue) diseaseLabel.getDeltaValue();
          k4map.put(diseaseLabel, (IntegrationLabelValue) EcoreUtil.copy(deltaLabel));

          _k1[n].set(k1map.get(diseaseLabel));
          _k2[n].set(k2map.get(diseaseLabel));
          _k3[n].set(k3map.get(diseaseLabel));
          _k4[n].set(deltaLabel);

          _k1[n].scale(b51);
          _k2[n].scale(b52);
          _k3[n].scale(b53);
          _k4[n].scale(b54);

          IntegrationLabelValue estDelta = _k1[n];
          estDelta.add(_k2[n]);
          estDelta.add(_k3[n]);
          estDelta.add(_k4[n]);

          estDelta.scale(h);
          ((IntegrationLabelValue) diseaseLabel.getProbeValue())
              .set(estDelta.add((IntegrationLabelValue) diseaseLabel.getTempValue()));
        }
        ++n;
      }

      // Now get the next delta values
      for (Decorator sdm : iDecorators)
        ((IntegrationDecorator) sdm)
            .calculateDelta(time, timeDelta, sdm.getLabelsToUpdate(threadnum, num_threads));
      for (Decorator sdm : iDecorators)
        ((IntegrationDecorator) sdm)
            .applyExternalDeltas(time, timeDelta, sdm.getLabelsToUpdate(threadnum, num_threads));

      // Step 5 in Runge Kutta Fehlberg.
      // Get the delta values out of each node label and
      // build a fifth estimate of the next value
      n = 0;
      for (Decorator sdm : iDecorators) {
        for (final Iterator<DynamicLabel> currentStateLabelIter =
                sdm.getLabelsToUpdate(threadnum, num_threads).iterator();
            currentStateLabelIter.hasNext(); ) {

          final IntegrationLabel diseaseLabel = (IntegrationLabel) currentStateLabelIter.next();

          IntegrationLabelValue deltaLabel = (IntegrationLabelValue) diseaseLabel.getDeltaValue();
          k5map.put(diseaseLabel, (IntegrationLabelValue) EcoreUtil.copy(deltaLabel));

          _k1[n].set(k1map.get(diseaseLabel));
          _k2[n].set(k2map.get(diseaseLabel));
          _k3[n].set(k3map.get(diseaseLabel));
          _k4[n].set(k4map.get(diseaseLabel));
          _k5[n].set(deltaLabel);

          _k1[n].scale(b61);
          _k2[n].scale(b62);
          _k3[n].scale(b63);
          _k4[n].scale(b64);
          _k5[n].scale(b65);

          IntegrationLabelValue estDelta = _k1[n];
          estDelta.add(_k2[n]);
          estDelta.add(_k3[n]);
          estDelta.add(_k4[n]);
          estDelta.add(_k5[n]);

          estDelta.scale(h);

          ((IntegrationLabelValue) diseaseLabel.getProbeValue())
              .set(estDelta.add((IntegrationLabelValue) diseaseLabel.getTempValue()));
        }
        ++n;
      }

      // Now get the next delta values
      for (Decorator sdm : iDecorators)
        ((IntegrationDecorator) sdm)
            .calculateDelta(time, timeDelta, sdm.getLabelsToUpdate(threadnum, num_threads));
      for (Decorator sdm : iDecorators)
        ((IntegrationDecorator) sdm)
            .applyExternalDeltas(time, timeDelta, sdm.getLabelsToUpdate(threadnum, num_threads));

      // Step 6 in Runge Kutta Fehlberg.
      // Calculate k6
      n = 0;
      for (Decorator sdm : iDecorators) {
        for (final Iterator<DynamicLabel> currentStateLabelIter =
                sdm.getLabelsToUpdate(threadnum, num_threads).iterator();
            currentStateLabelIter.hasNext(); ) {

          final IntegrationLabel diseaseLabel = (IntegrationLabel) currentStateLabelIter.next();

          IntegrationLabelValue deltaLabel = (IntegrationLabelValue) diseaseLabel.getDeltaValue();
          k6map.put(diseaseLabel, (IntegrationLabelValue) EcoreUtil.copy(deltaLabel));
        }
        ++n;
      }

      // Step 7 in Runge Kutta Fehlberg
      // Calculate the two estimates from k1, .. k6 values
      // and determine the maximum difference (error) between them.

      boolean success = true; // Were we able to update all labels without a large enough error?
      double maxerror = 0.0;
      n = 0;
      for (Decorator sdm : iDecorators) {
        for (final Iterator<DynamicLabel> currentStateLabelIter =
                sdm.getLabelsToUpdate(threadnum, num_threads).iterator();
            currentStateLabelIter.hasNext(); ) {

          final IntegrationLabel diseaseLabel = (IntegrationLabel) currentStateLabelIter.next();

          IntegrationLabelValue currentValue = (IntegrationLabelValue) diseaseLabel.getTempValue();

          _k1[n].set(k1map.get(diseaseLabel));
          _k3[n].set(k3map.get(diseaseLabel));
          _k4[n].set(k4map.get(diseaseLabel));
          _k5[n].set(k5map.get(diseaseLabel));
          _k6[n].set(k6map.get(diseaseLabel));

          _k1[n].scale(c1);
          _k3[n].scale(c3);
          _k4[n].scale(c4);
          _k6[n].scale(c6);

          // New Y
          IntegrationLabelValue yout =
              (IntegrationLabelValue) EcoreUtil.copy(_k1[n].add(_k3[n]).add(_k4[n]).add(_k6[n]));

          yout.scale(h);
          yout.add(currentValue);

          // Get the error
          _k1[n].set(k1map.get(diseaseLabel));
          _k3[n].set(k3map.get(diseaseLabel));
          _k4[n].set(k4map.get(diseaseLabel));
          _k5[n].set(k5map.get(diseaseLabel));
          _k6[n].set(k6map.get(diseaseLabel));

          _k1[n].scale(dc1);
          _k3[n].scale(dc3);
          _k4[n].scale(dc4);
          _k5[n].scale(dc5);
          _k6[n].scale(dc6);

          IntegrationLabelValue yerror =
              (IntegrationLabelValue)
                  EcoreUtil.copy(_k1[n].add(_k3[n]).add(_k4[n]).add(_k5[n]).add(_k6[n]));
          yerror.scale(h);

          yerror.divide((IntegrationLabelValue) diseaseLabel.getErrorScale());
          double error = yerror.max();
          error /= relativeTolerance;

          if (error > maxerror) {
            maxerror = error;
          }

          if (error <= 1.0)
            finalEstimate.put(diseaseLabel, (IntegrationLabelValue) EcoreUtil.copy(yout));
        }
        ++n;
      }

      jobs[threadnum].h = h;
      jobs[threadnum].maxerror = maxerror;
      try {
        stepSizeBarrier.await();
      } catch (InterruptedException ie) {
        // Should never happen
        Activator.logError(ie.getMessage(), ie);
      } catch (BrokenBarrierException bbe) {
        // Should never happen
        Activator.logError(bbe.getMessage(), bbe);
      }

      // At least one of the threads had to large of an error, fail
      if (this.maximumError > 1.0) success = false;

      // Are we done?
      if (success) {
        // Check to make sure
        if (this.smallestH > h)
          Activator.logError(
              "Error, h was less than the smallest, perhaps barrier process failed to execute? h:"
                  + h
                  + " vs "
                  + this.smallestH,
              new Exception());

        // Yes, hurrah, advance x using the step size h
        x += h;
        if (this.maximumError > ERRCON) h = SAFETY * h * Math.pow(this.maximumError, PGROW);
        else h = 5.0 * h;

        // Limit to max 1
        if (h > 1.0) h = 1.0;

        // Make sure we don't overshoot
        if (x < end && x + h > end) h = (end - x);

        // Update the current value to the new position
        for (Decorator sdm : iDecorators) {
          for (final Iterator<DynamicLabel> currentStateLabelIter =
                  sdm.getLabelsToUpdate(threadnum, num_threads).iterator();
              currentStateLabelIter.hasNext(); ) {
            final IntegrationLabel diseaseLabel = (IntegrationLabel) currentStateLabelIter.next();
            ((IntegrationLabelValue) diseaseLabel.getTempValue())
                .set(finalEstimate.get(diseaseLabel));
            ((IntegrationLabelValue) diseaseLabel.getProbeValue())
                .set(finalEstimate.get(diseaseLabel));
          }
        }

        // Wait until all other threads have updated the current value
        try {
          updateDoneBarrier.await();
        } catch (InterruptedException ie) {
          // Should never happen
          Activator.logError(ie.getMessage(), ie);
        } catch (BrokenBarrierException bbe) {
          // Should never happen
          Activator.logError(bbe.getMessage(), bbe);
        }

        double progress = (end - x < 0.0) ? 1.0 : 1.0 - (end - x);
        jobs[threadnum].setProgress(progress);
        if (x > nextProgressReport) {
          // Get the progress for all threads
          for (int i = 0; i < num_threads; ++i)
            if (i != threadnum && jobs[i] != null) progress += jobs[i].getProgress();
          progress /= num_threads;
          for (Decorator sdm : iDecorators) sdm.setProgress(progress);
          nextProgressReport += nextProgressReportStep;
        }

      } else {
        // At least one thread failed, change the step size

        // Problem, error too big, we need to reduce the step size
        delta = SAFETY * h * Math.pow(this.maximumError, PSHRNK);
        if (h > 0.0) h = (delta > 0.1 * h) ? delta : 0.1 * h;
        else h = (delta > 0.1 * h) ? 0.1 * h : delta;

        // We didn't succeed.

        // Reset the estimated value back to the original, the step size
        // has been reduced so we well try again.
        // Set the estimated value back to the current original value
        for (Decorator sdm : iDecorators) {
          for (final Iterator<DynamicLabel> currentStateLabelIter =
                  sdm.getLabelsToUpdate(threadnum, num_threads).iterator();
              currentStateLabelIter.hasNext(); ) {
            final IntegrationLabel diseaseLabel = (IntegrationLabel) currentStateLabelIter.next();
            ((IntegrationLabelValue) diseaseLabel.getProbeValue())
                .set((IntegrationLabelValue) diseaseLabel.getTempValue());
          }
        }
      }
    } // While x < end

    jobs[threadnum].t = x;
    jobs[threadnum].h = h;

    // Remember the step size and position in the solver
    this.setStepSize(h);
    this.setCurrentX(x);

    // We're done
    for (Decorator sdm : iDecorators) {
      for (final Iterator<DynamicLabel> currentStateLabelIter =
              sdm.getLabelsToUpdate(threadnum, num_threads).iterator();
          currentStateLabelIter.hasNext(); ) {
        final IntegrationLabel diseaseLabel = (IntegrationLabel) currentStateLabelIter.next();

        // This is the next state for the label
        IntegrationLabelValue nextState = (IntegrationLabelValue) diseaseLabel.getNextValue();
        // This is the original current state at the previous cycle
        IntegrationLabelValue originalState =
            (IntegrationLabelValue) diseaseLabel.getCurrentValue();
        // This is the final value calculated at position x.
        IntegrationLabelValue newValue = finalEstimate.get(diseaseLabel);
        // x could be larger than the requested cycle, so we do a linear interpolation
        // to fit it exactly to the requested cycle
        // *** Not needed since we always end exactly at the requested cycle
        // adjustValuesToCycle(originalState, newValue, x, cycle);

        // New value has been modified here to fit the requested cycle
        nextState.set(newValue);
        // Do any model specific work for instance add noise
        ((IntegrationDecorator) sdm).doModelSpecificAdjustments((LabelValue) nextState);
        // The next value is valid now.
        diseaseLabel.setNextValueValid(true);
      }
    }
  }