17c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom/* 27c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom * Copyright (C) 2011 The Android Open Source Project 37c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom * 47c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom * Licensed under the Apache License, Version 2.0 (the "License"); 57c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom * you may not use this file except in compliance with the License. 67c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom * You may obtain a copy of the License at 77c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom * 87c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom * http://www.apache.org/licenses/LICENSE-2.0 97c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom * 107c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom * Unless required by applicable law or agreed to in writing, software 117c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom * distributed under the License is distributed on an "AS IS" BASIS, 127c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom * See the License for the specific language governing permissions and 147c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom * limitations under the License. 157c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom */ 167c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom 171c83cbc4a817acbd7f9abb5b29a2d418a958e6a1Andreas Gampeimport java.lang.reflect.*; 187c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstromimport java.util.ArrayList; 197c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstromimport java.util.Arrays; 207c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstromimport java.util.Collections; 217c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstromimport java.util.HashMap; 22f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampeimport java.util.HashSet; 237c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstromimport java.util.List; 247c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstromimport java.util.Map; 25f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampeimport java.util.Set; 267c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom 277c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom// Run on host with: 287c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom// javac ThreadTest.java && java ThreadStress && rm *.class 29f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe// Through run-test: 30f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe// test/run-test {run-test-args} 004-ThreadStress [Main {ThreadStress-args}] 31f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe// (It is important to pass Main if you want to give parameters...) 32f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe// 33f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe// ThreadStress command line parameters: 34f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe// -n X ............ number of threads 35f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe// -o X ............ number of overall operations 36f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe// -t X ............ number of operations per thread 37f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe// --dumpmap ....... print the frequency map 38f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe// -oom:X .......... frequency of OOM (double) 39f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe// -alloc:X ........ frequency of Alloc 40f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe// -stacktrace:X ... frequency of StackTrace 41f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe// -exit:X ......... frequency of Exit 42f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe// -sleep:X ........ frequency of Sleep 43f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe// -wait:X ......... frequency of Wait 44f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe// -timedwait:X .... frequency of TimedWait 45f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe 461c83cbc4a817acbd7f9abb5b29a2d418a958e6a1Andreas Gampepublic class Main implements Runnable { 477c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom 484514d3c0e69a49f5dbe19138330a2bb2aee36d63Brian Carlstrom public static final boolean DEBUG = false; 497c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom 50f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe private static abstract class Operation { 51f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe /** 52f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe * Perform the action represented by this operation. Returns true if the thread should 53f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe * continue. 54f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe */ 55f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe public abstract boolean perform(); 56f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 57f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe 58f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe private final static class OOM extends Operation { 59f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe @Override 60f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe public boolean perform() { 61f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe try { 62f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe List<byte[]> l = new ArrayList<byte[]>(); 63f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe while (true) { 64f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe l.add(new byte[1024]); 65f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 66f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } catch (OutOfMemoryError e) { 67f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 68f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe return true; 69f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 70f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 71f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe 72f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe private final static class SigQuit extends Operation { 73f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe private final static int sigquit; 74f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe private final static Method kill; 75f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe private final static int pid; 76f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe 77f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe static { 78f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe int pidTemp = -1; 79f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe int sigquitTemp = -1; 80f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe Method killTemp = null; 81f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe 82f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe try { 83f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe Class<?> osClass = Class.forName("android.system.Os"); 84f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe Method getpid = osClass.getDeclaredMethod("getpid"); 85f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe pidTemp = (Integer)getpid.invoke(null); 86f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe 87f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe Class<?> osConstants = Class.forName("android.system.OsConstants"); 88f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe Field sigquitField = osConstants.getDeclaredField("SIGQUIT"); 89f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe sigquitTemp = (Integer)sigquitField.get(null); 90f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe 91f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe killTemp = osClass.getDeclaredMethod("kill", int.class, int.class); 92f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } catch (Exception e) { 93f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe if (!e.getClass().getName().equals("ErrnoException")) { 94f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe e.printStackTrace(System.out); 95f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 96f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 97f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe 98f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe pid = pidTemp; 99f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe sigquit = sigquitTemp; 100f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe kill = killTemp; 101f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 102f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe 103f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe @Override 104f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe public boolean perform() { 105f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe try { 106f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe kill.invoke(null, pid, sigquit); 107f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } catch (Exception e) { 108f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe if (!e.getClass().getName().equals("ErrnoException")) { 109f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe e.printStackTrace(System.out); 110f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 111f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 112f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe return true; 113f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 114f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 115f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe 116f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe private final static class Alloc extends Operation { 117f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe @Override 118f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe public boolean perform() { 119f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe try { 120f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe List<byte[]> l = new ArrayList<byte[]>(); 121f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe for (int i = 0; i < 1024; i++) { 122f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe l.add(new byte[1024]); 123f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 124f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } catch (OutOfMemoryError e) { 125f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 126f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe return true; 127f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 128f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 129f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe 130f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe private final static class StackTrace extends Operation { 131f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe @Override 132f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe public boolean perform() { 133f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe Thread.currentThread().getStackTrace(); 134f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe return true; 135f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 136f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 137f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe 138f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe private final static class Exit extends Operation { 139f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe @Override 140f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe public boolean perform() { 141f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe return false; 142f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 143f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 144f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe 145f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe private final static class Sleep extends Operation { 146f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe @Override 147f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe public boolean perform() { 148f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe try { 149f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe Thread.sleep(100); 150f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } catch (InterruptedException ignored) { 151f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 152f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe return true; 153f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 154f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 1554cd121ef0cb35fced70c7d9de378277be7a727d9Elliott Hughes 156f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe private final static class TimedWait extends Operation { 157f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe private final Object lock; 1587c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom 159f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe public TimedWait(Object lock) { 160f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe this.lock = lock; 161f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 162f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe 163f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe @Override 164f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe public boolean perform() { 165f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe synchronized (lock) { 166f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe try { 167f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe lock.wait(100, 0); 168f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } catch (InterruptedException ignored) { 169f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 170f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 171f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe return true; 1727c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom } 1737c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom } 1747c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom 175f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe private final static class Wait extends Operation { 176f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe private final Object lock; 177f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe 178f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe public Wait(Object lock) { 179f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe this.lock = lock; 180f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 181f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe 182f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe @Override 183f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe public boolean perform() { 184f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe synchronized (lock) { 185f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe try { 186f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe lock.wait(); 187f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } catch (InterruptedException ignored) { 188f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 189f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 190f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe return true; 191f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 192f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 193f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe 194f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe private final static class SyncAndWork extends Operation { 195f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe private final Object lock; 196f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe 197f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe public SyncAndWork(Object lock) { 198f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe this.lock = lock; 199f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 200f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe 201f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe @Override 202f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe public boolean perform() { 203f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe synchronized (lock) { 204f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe try { 205f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe Thread.sleep((int)(Math.random()*10)); 206f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } catch (InterruptedException ignored) { 207f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 208f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 209f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe return true; 210f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 211f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 212f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe 213f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe private final static Map<Operation, Double> createDefaultFrequencyMap(Object lock) { 214f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe Map<Operation, Double> frequencyMap = new HashMap<Operation, Double>(); 215f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe frequencyMap.put(new OOM(), 0.005); // 1/200 216f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe frequencyMap.put(new SigQuit(), 0.095); // 19/200 217f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe frequencyMap.put(new Alloc(), 0.3); // 60/200 218f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe frequencyMap.put(new StackTrace(), 0.1); // 20/200 219f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe frequencyMap.put(new Exit(), 0.25); // 50/200 220f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe frequencyMap.put(new Sleep(), 0.125); // 25/200 221f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe frequencyMap.put(new TimedWait(lock), 0.05); // 10/200 222f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe frequencyMap.put(new Wait(lock), 0.075); // 15/200 223f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe 224f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe return frequencyMap; 225f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 226f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe 227f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe private final static Map<Operation, Double> createLockFrequencyMap(Object lock) { 228f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe Map<Operation, Double> frequencyMap = new HashMap<Operation, Double>(); 229f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe frequencyMap.put(new Sleep(), 0.2); 230f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe frequencyMap.put(new TimedWait(lock), 0.2); 231f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe frequencyMap.put(new Wait(lock), 0.2); 232f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe frequencyMap.put(new SyncAndWork(lock), 0.4); 233f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe 234f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe return frequencyMap; 235f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 236f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe 2377c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom public static void main(String[] args) throws Exception { 238f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe parseAndRun(args); 239f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 2407c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom 241f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe private static Map<Operation, Double> updateFrequencyMap(Map<Operation, Double> in, 242f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe Object lock, String arg) { 243f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe String split[] = arg.split(":"); 244f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe if (split.length != 2) { 245f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe throw new IllegalArgumentException("Can't split argument " + arg); 246f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 247f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe double d; 248f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe try { 249f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe d = Double.parseDouble(split[1]); 250f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } catch (Exception e) { 251f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe throw new IllegalArgumentException(e); 252f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 253f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe if (d < 0) { 254f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe throw new IllegalArgumentException(arg + ": value must be >= 0."); 255f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 256f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe Operation op = null; 257f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe if (split[0].equals("-oom")) { 258f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe op = new OOM(); 259f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } else if (split[0].equals("-sigquit")) { 260f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe op = new SigQuit(); 261f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } else if (split[0].equals("-alloc")) { 262f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe op = new Alloc(); 263f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } else if (split[0].equals("-stacktrace")) { 264f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe op = new StackTrace(); 265f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } else if (split[0].equals("-exit")) { 266f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe op = new Exit(); 267f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } else if (split[0].equals("-sleep")) { 268f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe op = new Sleep(); 269f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } else if (split[0].equals("-wait")) { 270f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe op = new Wait(lock); 271f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } else if (split[0].equals("-timedwait")) { 272f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe op = new TimedWait(lock); 273f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } else { 274f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe throw new IllegalArgumentException("Unknown arg " + arg); 275f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 276f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe 277f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe if (in == null) { 278f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe in = new HashMap<Operation, Double>(); 279f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 280f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe in.put(op, d); 2817c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom 282f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe return in; 283f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 284f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe 285f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe private static void normalize(Map<Operation, Double> map) { 286f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe double sum = 0; 287f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe for (Double d : map.values()) { 288f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe sum += d; 289f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 290f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe if (sum == 0) { 291f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe throw new RuntimeException("No elements!"); 292f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 293f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe if (sum != 1.0) { 294f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe // Avoid ConcurrentModificationException. 295f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe Set<Operation> tmp = new HashSet<>(map.keySet()); 296f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe for (Operation op : tmp) { 297f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe map.put(op, map.get(op) / sum); 298f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 299f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 300f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 301f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe 302f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe public static void parseAndRun(String[] args) throws Exception { 303f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe int numberOfThreads = -1; 304f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe int totalOperations = -1; 305f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe int operationsPerThread = -1; 306f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe Object lock = new Object(); 307f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe Map<Operation, Double> frequencyMap = null; 308f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe boolean dumpMap = false; 309f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe 310f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe if (args != null) { 311f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe for (int i = 0; i < args.length; i++) { 312f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe if (args[i].equals("-n")) { 313f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe i++; 314f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe numberOfThreads = Integer.parseInt(args[i]); 315f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } else if (args[i].equals("-o")) { 316f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe i++; 317f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe totalOperations = Integer.parseInt(args[i]); 318f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } else if (args[i].equals("-t")) { 319f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe i++; 320f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe operationsPerThread = Integer.parseInt(args[i]); 321f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } else if (args[i].equals("--locks-only")) { 322f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe lock = new Object(); 323f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe frequencyMap = createLockFrequencyMap(lock); 324f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } else if (args[i].equals("--dumpmap")) { 325f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe dumpMap = true; 326f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } else { 327f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe frequencyMap = updateFrequencyMap(frequencyMap, lock, args[i]); 328f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 329f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 330f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 3317c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom 332f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe if (totalOperations != -1 && operationsPerThread != -1) { 333f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe throw new IllegalArgumentException( 334f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe "Specified both totalOperations and operationsPerThread"); 335f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 336f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe 337f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe if (numberOfThreads == -1) { 338f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe numberOfThreads = 5; 339f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 340f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe 341f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe if (totalOperations == -1) { 342f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe totalOperations = 1000; 343f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 344f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe 345f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe if (operationsPerThread == -1) { 346f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe operationsPerThread = totalOperations/numberOfThreads; 347f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 348f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe 349f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe if (frequencyMap == null) { 350f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe frequencyMap = createDefaultFrequencyMap(lock); 351f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 352f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe normalize(frequencyMap); 353f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe 354f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe if (dumpMap) { 355f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe System.out.println(frequencyMap); 356f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 357f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe 358f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe runTest(numberOfThreads, operationsPerThread, lock, frequencyMap); 359f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 360f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe 361f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe public static void runTest(final int numberOfThreads, final int operationsPerThread, 362f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe final Object lock, Map<Operation, Double> frequencyMap) 363f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe throws Exception { 3647c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom // Each thread is going to do operationsPerThread 3657c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom // operations. The distribution of operations is determined by 3667c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom // the Operation.frequency values. We fill out an Operation[] 3677c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom // for each thread with the operations it is to perform. The 3687c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom // Operation[] is shuffled so that there is more random 3697c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom // interactions between the threads. 3707c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom 3717c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom // Fill in the Operation[] array for each thread by laying 3727c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom // down references to operation according to their desired 3737c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom // frequency. 3741c83cbc4a817acbd7f9abb5b29a2d418a958e6a1Andreas Gampe final Main[] threadStresses = new Main[numberOfThreads]; 3757c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom for (int t = 0; t < threadStresses.length; t++) { 3767c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom Operation[] operations = new Operation[operationsPerThread]; 3777c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom int o = 0; 3787c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom LOOP: 3797c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom while (true) { 380f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe for (Operation op : frequencyMap.keySet()) { 381f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe int freq = (int)(frequencyMap.get(op) * operationsPerThread); 382f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe for (int f = 0; f < freq; f++) { 3837c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom if (o == operations.length) { 3847c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom break LOOP; 3857c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom } 3867c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom operations[o] = op; 3877c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom o++; 3887c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom } 3897c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom } 3907c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom } 3917c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom // Randomize the oepration order 3927c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom Collections.shuffle(Arrays.asList(operations)); 3931c83cbc4a817acbd7f9abb5b29a2d418a958e6a1Andreas Gampe threadStresses[t] = new Main(lock, t, operations); 3947c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom } 3957c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom 396f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe // Enable to dump operation counts per thread to make sure its 3977c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom // sane compared to Operation.frequency 3987c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom if (DEBUG) { 3997c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom for (int t = 0; t < threadStresses.length; t++) { 400f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe Operation[] operations = threadStresses[t].operations; 4017c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom Map<Operation, Integer> distribution = new HashMap<Operation, Integer>(); 4027c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom for (Operation operation : operations) { 4037c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom Integer ops = distribution.get(operation); 4047c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom if (ops == null) { 4057c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom ops = 1; 4067c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom } else { 4077c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom ops++; 4087c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom } 4097c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom distribution.put(operation, ops); 4107c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom } 4117c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom System.out.println("Distribution for " + t); 412f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe for (Operation op : frequencyMap.keySet()) { 4137c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom System.out.println(op + " = " + distribution.get(op)); 4147c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom } 4157c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom } 4167c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom } 4177c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom 4187c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom // Create the runners for each thread. The runner Thread 4197c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom // ensures that thread that exit due to Operation.EXIT will be 4207c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom // restarted until they reach their desired 4217c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom // operationsPerThread. 4227c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom Thread[] runners = new Thread[numberOfThreads]; 4237c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom for (int r = 0; r < runners.length; r++) { 4241c83cbc4a817acbd7f9abb5b29a2d418a958e6a1Andreas Gampe final Main ts = threadStresses[r]; 4255f51d4b80058236759fea1d932470a57f348c199Mathieu Chartier runners[r] = new Thread("Runner thread " + r) { 4261c83cbc4a817acbd7f9abb5b29a2d418a958e6a1Andreas Gampe final Main threadStress = ts; 4277c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom public void run() { 4287c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom int id = threadStress.id; 4295f51d4b80058236759fea1d932470a57f348c199Mathieu Chartier System.out.println("Starting worker for " + id); 4307c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom while (threadStress.nextOperation < operationsPerThread) { 4315f51d4b80058236759fea1d932470a57f348c199Mathieu Chartier Thread thread = new Thread(ts, "Worker thread " + id); 4327c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom thread.start(); 4337c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom try { 4347c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom thread.join(); 4357c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom } catch (InterruptedException e) { 4367c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom } 4377c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom System.out.println("Thread exited for " + id + " with " 4387c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom + (operationsPerThread - threadStress.nextOperation) 4397c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom + " operations remaining."); 4407c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom } 4411c83cbc4a817acbd7f9abb5b29a2d418a958e6a1Andreas Gampe System.out.println("Finishing worker"); 4427c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom } 4437c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom }; 4447c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom } 4457c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom 4467c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom // The notifier thread is a daemon just loops forever to wake 4477c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom // up threads in Operation.WAIT 448f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe if (lock != null) { 449f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe Thread notifier = new Thread("Notifier") { 450f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe public void run() { 451f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe while (true) { 452f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe synchronized (lock) { 453f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe lock.notifyAll(); 454f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 4557c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom } 4567c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom } 457f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe }; 458f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe notifier.setDaemon(true); 459f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe notifier.start(); 460f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe } 4617c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom 4627c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom for (int r = 0; r < runners.length; r++) { 4637c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom runners[r].start(); 4647c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom } 4657c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom for (int r = 0; r < runners.length; r++) { 4667c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom runners[r].join(); 4677c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom } 4687c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom } 4697c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom 4707c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom private final Operation[] operations; 4717c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom private final Object lock; 4727c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom private final int id; 4737c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom 4747c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom private int nextOperation; 4757c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom 4761c83cbc4a817acbd7f9abb5b29a2d418a958e6a1Andreas Gampe private Main(Object lock, int id, Operation[] operations) { 4777c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom this.lock = lock; 4787c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom this.id = id; 4797c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom this.operations = operations; 4807c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom } 4817c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom 4827c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom public void run() { 4837c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom try { 4847c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom if (DEBUG) { 4857c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom System.out.println("Starting ThreadStress " + id); 4867c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom } 4877c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom while (nextOperation < operations.length) { 4887c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom Operation operation = operations[nextOperation]; 4897c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom if (DEBUG) { 4907c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom System.out.println("ThreadStress " + id 4917c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom + " operation " + nextOperation 4927c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom + " is " + operation); 4937c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom } 4947c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom nextOperation++; 495f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe if (!operation.perform()) { 496f2fdc7368c5fd5d9cbb4bd1d962b887e87f0654cAndreas Gampe return; 4977c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom } 4987c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom } 4994514d3c0e69a49f5dbe19138330a2bb2aee36d63Brian Carlstrom } finally { 5007c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom if (DEBUG) { 5017c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom System.out.println("Finishing ThreadStress for " + id); 5027c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom } 5037c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom } 5047c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom } 5051c83cbc4a817acbd7f9abb5b29a2d418a958e6a1Andreas Gampe 5067c6deaa3382f1f4fb0f591af206f03045c6e9004Brian Carlstrom} 507