/*
 *   Copyright 2014 Florida Institute for Human and Machine Cognition (IHMC)
 *    
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *    
 *    http://www.apache.org/licenses/LICENSE-2.0
 *    
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 *    
 *    Written by Jesper Smith with assistance from IHMC team members
 */
package us.ihmc.realtime;

import us.ihmc.affinity.CPUTopology;
import us.ihmc.affinity.Processor;

public class TestCyclic
{
   public static void main(String[] args) throws InterruptedException
   {
      final int periodInNS = 1000000;
      final int iterations = 60000;
      final double duration = (double) periodInNS * (double) iterations / 1e9;

      final boolean endless = (args.length > 0) && (args[0].equals("--endless"));
      if (endless)
      {
         System.out.println("You can cancel this test by pressing Ctrl+C");
      }
      else
      {
         System.out.println("Estimated duration: " + duration + " seconds");
      }

      PriorityParameters priorityParameters = new PriorityParameters(99);
      PeriodicParameters periodicParameters = new PeriodicParameters(new MonotonicTime(0, periodInNS));

      final double[] jitterValues = new double[iterations];

      RealtimeThread periodicRealtimeThread = new RealtimeThread(priorityParameters, periodicParameters)
      {
         private void perform(int run)
         {
            super.waitForNextPeriod();
            long previousTime = System.nanoTime();

            for (int i = 0; i < iterations; i++)
            {
               super.waitForNextPeriod();
               long newTime = System.nanoTime();
               jitterValues[i] = Math.abs(newTime - previousTime - periodInNS) * 1.0e-3;
               previousTime = newTime;
            }

            double average = 0.0;
            double maximum = 0.0;
            double standardDeviation = 0.0;

            for (double value : jitterValues)
            {
               average += value / iterations;
               maximum = Math.max(maximum, value);
            }
            for (double value : jitterValues)
            {
               standardDeviation += Math.pow(value - average, 2);
            }
            standardDeviation = Math.sqrt(standardDeviation / iterations);

            System.out.format("[%d] Jitter: average = %.2f us, maximum = %.2f us, standard deviation = %.2f us%n", run, average, maximum, standardDeviation);
         }

         @Override
         public void run()
         {
            int run = 1;
            do
            {
               perform(run++);
            }
            while (endless);
         }
      };

      System.out.println("Pinning the periodic thread to processor 1");
      Processor testProcessor = new CPUTopology().getPackage(0).getCore(1).getDefaultProcessor();
      periodicRealtimeThread.setAffinity(testProcessor);

      periodicRealtimeThread.start();
      periodicRealtimeThread.join();
   }
}

@@ -1305,32 +1305,95 @@
    else%0A      %7B%0A
+         System.out.println(%22Iteration count: %22 + iterations);%0A
          System.
@@ -1645,69 +1645,8 @@
 );%0A%0A
-      final double%5B%5D jitterValues = new double%5Biterations%5D;%0A%0A
     
@@ -1820,84 +1820,93 @@
     
-super.waitForNextPeriod();%0A            long previousTime = System.nanoTime()
+long previousTime = 0;%0A            long avgJitter = 0;%0A            long maxJitter = 0
 ;%0A%0A 
@@ -1919,17 +1919,16 @@
      for
- 
 (int i =
@@ -1928,17 +1928,18 @@
 int i = 
-0
+-1
 ; i %3C it
@@ -2028,131 +2028,38 @@
     
-long newTime = System.nanoTime();%0A               jitterValues%5Bi%5D = Math.abs(newTime - previousTime - periodInNS) * 1.0e-3;%0A
+if(i %3C 0)%0A               %7B%0A   
     
@@ -2088,15 +2088,25 @@
 e = 
-new
+System.nano
 Time
+()
 ;%0A  
@@ -2119,279 +2119,304 @@
     
+ 
-%7D%0A%0A            double average = 0.0;%0A            double maximum = 0.0;%0A            double standardDeviation = 0.0;%0A%0A            for (double value : jitterValues)%0A            %7B%0A               average += value / iterations;%0A               maximum = Math.max(maximum, value)
+     continue;%0A               %7D%0A%0A               long newTime = System.nanoTime();%0A               long jitter = Math.abs(newTime - previousTime - periodInNS);%0A%0A               if(jitter %3E maxJitter) %7B maxJitter = jitter; %7D%0A               avgJitter += jitter;%0A%0A               previousTime = newTime
 ;%0A  
@@ -2419,32 +2419,33 @@
 ;%0A            %7D%0A
+%0A
             for 
@@ -2445,208 +2445,145 @@
    f
-or (
+inal 
 double 
-value : jitterValues)%0A            %7B%0A               standardDeviation += Math.pow(value - average, 2);%0A            %7D%0A            standardDeviation = Math.sqrt(standardDeviation / iterations)
+usAvgJitter = (double) avgJitter / (double) iterations / 1e3;%0A            final double usMaxJitter = (double) maxJitter / 1e3
 ;%0A%0A 
@@ -2631,19 +2631,15 @@
 : av
-erage
+g
  = %25.
-2
+4
 f us
@@ -2647,97 +2647,52 @@
  max
-imum
  = %25.
-2f us, standard deviation = %25.2f us%25n%22, run, average, maximum, standardDeviation
+4f us%25n%22, run, usAvgJitter, usMaxJitter
 );%0A 
@@ -2784,16 +2784,17 @@
 un = 1;%0A
+%0A
         
@@ -2803,37 +2803,10 @@
   do
-%0A            %7B%0A             
  
+%7B
  per
@@ -2817,28 +2817,16 @@
 (run++);
-%0A           
  %7D%0A     

Revert changes to `TestCyclic`.