content: /*
   * Copyright (C) 2013 The Android Open Source Project
   *
   * 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.
   */
  
  public class Main {
      private static final int TEST_TIME = 5;
  
      public static void main(String[] args) {
          System.out.println("Running (" + TEST_TIME + " seconds) ...");
          InfiniteDoWhileLoopWithLong doWhileLoopWithLong = new InfiniteDoWhileLoopWithLong();
          SimpleLoopThread[] simpleLoops = {
                  new InfiniteForLoop(),
                  new InfiniteWhileLoop(),
                  new InfiniteWhileLoopWithIntrinsic(),
                  new InfiniteDoWhileLoop(),
                  new MakeGarbage(),
                  new InfiniteWhileLoopWithSpecialReturnArgOrConst(new SpecialMethods1()),
                  new InfiniteWhileLoopWithSpecialReturnArgOrConst(new SpecialMethods2()),
                  new InfiniteWhileLoopWithSpecialPutOrNop(new SpecialMethods1()),
                  new InfiniteWhileLoopWithSpecialPutOrNop(new SpecialMethods2()),
                  new InfiniteWhileLoopWithSpecialConstOrIGet(new SpecialMethods1()),
                  new InfiniteWhileLoopWithSpecialConstOrIGet(new SpecialMethods2()),
                  new InfiniteWhileLoopWithSpecialConstOrIGetInTryCatch(new SpecialMethods1()),
                  new InfiniteWhileLoopWithSpecialConstOrIGetInTryCatch(new SpecialMethods2()),
          };
          doWhileLoopWithLong.start();
          for (SimpleLoopThread loop : simpleLoops) {
              loop.start();
          }
          for (int i = 0; i < TEST_TIME; i++) {
            Runtime.getRuntime().gc();
            System.out.println(".");
            sleep(1000);
          }
          doWhileLoopWithLong.stopNow();
          for (SimpleLoopThread loop : simpleLoops) {
              loop.stopNow();
          }
          System.out.println("Done.");
      }
  
      public static void sleep(int ms) {
          try {
              Thread.sleep(ms);
          } catch (InterruptedException ie) {
              System.err.println("sleep was interrupted");
          }
      }
  }
  
  class SimpleLoopThread extends Thread {
    volatile protected boolean keepGoing = true;
    public void stopNow() {
      keepGoing = false;
    }
  }
  
  interface SpecialMethodInterface {
    long ReturnArgOrConst(long arg);
    void PutOrNop(long arg);
    long ConstOrIGet();
  }
  
  class SpecialMethods1 implements SpecialMethodInterface {
    public long ReturnArgOrConst(long arg) {
      return 42L;
    }
    public void PutOrNop(long arg) {
    }
    public long ConstOrIGet() {
      return 42L;
    }
  }
  
  class SpecialMethods2 implements SpecialMethodInterface {
    public long value = 42L;
    public long ReturnArgOrConst(long arg) {
      return arg;
    }
    public void PutOrNop(long arg) {
      value = arg;
    }
    public long ConstOrIGet() {
      return value;
    }
  }
  
  class InfiniteWhileLoopWithSpecialReturnArgOrConst extends SimpleLoopThread {
    private SpecialMethodInterface smi;
    public InfiniteWhileLoopWithSpecialReturnArgOrConst(SpecialMethodInterface smi) {
      this.smi = smi;
    }
    public void run() {
      long i = 0L;
      while (keepGoing) {
        i += smi.ReturnArgOrConst(i);
      }
    }
  }
  
  class InfiniteWhileLoopWithSpecialPutOrNop extends SimpleLoopThread {
    private SpecialMethodInterface smi;
    public InfiniteWhileLoopWithSpecialPutOrNop(SpecialMethodInterface smi) {
      this.smi = smi;
    }
    public void run() {
      long i = 0L;
      while (keepGoing) {
        smi.PutOrNop(i);
        i++;
      }
    }
  }
  
  class InfiniteWhileLoopWithSpecialConstOrIGet extends SimpleLoopThread {
    private SpecialMethodInterface smi;
    public InfiniteWhileLoopWithSpecialConstOrIGet(SpecialMethodInterface smi) {
      this.smi = smi;
    }
    public void run() {
      long i = 0L;
      while (keepGoing) {
        i += smi.ConstOrIGet();
      }
    }
  }
  
  class InfiniteWhileLoopWithSpecialConstOrIGetInTryCatch extends SimpleLoopThread {
    private SpecialMethodInterface smi;
    public InfiniteWhileLoopWithSpecialConstOrIGetInTryCatch(SpecialMethodInterface smi) {
      this.smi = smi;
    }
    public void run() {
      try {
        long i = 0L;
        while (keepGoing) {
          i += smi.ConstOrIGet();
        }
      } catch (Throwable ignored) { }
    }
  }
  
  class InfiniteWhileLoopWithIntrinsic extends SimpleLoopThread {
    private String[] strings = { "a", "b", "c", "d" };
    private int sum = 0;
    public void run() {
      int i = 0;
      while (keepGoing) {
        i++;
        sum += strings[i & 3].length();
      }
    }
  }
  
  class InfiniteDoWhileLoopWithLong extends Thread {
    volatile private long keepGoing = 7L;
    public void run() {
      int i = 0;
      do {
        i++;
      } while (keepGoing >= 4L);
    }
    public void stopNow() {
      keepGoing = 1L;
    }
  }
  
  class InfiniteWhileLoop extends SimpleLoopThread {
    public void run() {
      int i = 0;
      while (keepGoing) {
        i++;
      }
    }
  }
  
  class InfiniteDoWhileLoop extends SimpleLoopThread {
    public void run() {
      int i = 0;
      do {
        i++;
      } while (keepGoing);
    }
  }
  
  class InfiniteForLoop extends SimpleLoopThread {
    public void run() {
      int i = 0;
      for (int j = 0; keepGoing; j++) {
        i += j;
      }
    }
  }
  
  class MakeGarbage extends SimpleLoopThread {
    public void run() {
      while (keepGoing) {
        byte[] garbage = new byte[100000];
      }
    }
  }
  