/*
 * Copyright (C) 2011 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.
 */

import android.system.ErrnoException;
import android.system.Os;
import android.system.OsConstants;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

// Run on host with:
//   javac ThreadTest.java && java ThreadStress && rm *.class
class ThreadStress implements Runnable {

    public static final boolean DEBUG = false;

    enum Operation {
        OOM(1),
        SIGQUIT(19),
        ALLOC(60),
        STACKTRACE(20),
        EXIT(50),

        SLEEP(25),
        TIMED_WAIT(10),
        WAIT(15);

        private final int frequency;
        Operation(int frequency) {
            this.frequency = frequency;
        }
    }

    public static void main(String[] args) throws Exception {

        final int numberOfThreads = 5;
        final int totalOperations = 1000;
        final int operationsPerThread = totalOperations/numberOfThreads;

        // Lock used to notify threads performing Operation.WAIT
        final Object lock = new Object();

        // Each thread is going to do operationsPerThread
        // operations. The distribution of operations is determined by
        // the Operation.frequency values. We fill out an Operation[]
        // for each thread with the operations it is to perform. The
        // Operation[] is shuffled so that there is more random
        // interactions between the threads.

        // The simple-minded filling in of Operation[] based on
        // Operation.frequency below won't have even have close to a
        // reasonable distribution if the count of Operation
        // frequencies is greater than the total number of
        // operations. So here we do a quick sanity check in case
        // people tweak the constants above.
        int operationCount = 0;
        for (Operation op : Operation.values()) {
            operationCount += op.frequency;
        }
        if (operationCount > operationsPerThread) {
            throw new AssertionError(operationCount + " > " + operationsPerThread);
        }

        // Fill in the Operation[] array for each thread by laying
        // down references to operation according to their desired
        // frequency.
        final ThreadStress[] threadStresses = new ThreadStress[numberOfThreads];
        for (int t = 0; t < threadStresses.length; t++) {
            Operation[] operations = new Operation[operationsPerThread];
            int o = 0;
            LOOP:
            while (true) {
                for (Operation op : Operation.values()) {
                    for (int f = 0; f < op.frequency; f++) {
                        if (o == operations.length) {
                            break LOOP;
                        }
                        operations[o] = op;
                        o++;
                    }
                }
            }
            // Randomize the oepration order
            Collections.shuffle(Arrays.asList(operations));
            threadStresses[t] = new ThreadStress(lock, t, operations);
        }

        // Enable to dump operation counds per thread to make sure its
        // sane compared to Operation.frequency
        if (DEBUG) {
            for (int t = 0; t < threadStresses.length; t++) {
                Operation[] operations = new Operation[operationsPerThread];
                Map<Operation, Integer> distribution = new HashMap<Operation, Integer>();
                for (Operation operation : operations) {
                    Integer ops = distribution.get(operation);
                    if (ops == null) {
                        ops = 1;
                    } else {
                        ops++;
                    }
                    distribution.put(operation, ops);
                }
                System.out.println("Distribution for " + t);
                for (Operation op : Operation.values()) {
                    System.out.println(op + " = " + distribution.get(op));
                }
            }
        }

        // Create the runners for each thread. The runner Thread
        // ensures that thread that exit due to Operation.EXIT will be
        // restarted until they reach their desired
        // operationsPerThread.
        Thread[] runners = new Thread[numberOfThreads];
        for (int r = 0; r < runners.length; r++) {
            final ThreadStress ts = threadStresses[r];
            runners[r] = new Thread("Runner thread " + r) {
                final ThreadStress threadStress = ts;
                public void run() {
                    int id = threadStress.id;
                    System.out.println("Starting worker for " + id);
                    while (threadStress.nextOperation < operationsPerThread) {
                        Thread thread = new Thread(ts, "Worker thread " + id);
                        thread.start();
                        try {
                            thread.join();
                        } catch (InterruptedException e) {
                        }
                        System.out.println("Thread exited for " + id + " with "
                                           + (operationsPerThread - threadStress.nextOperation)
                                           + " operations remaining.");
                    }
                    System.out.println("Finishing worker for " + id);
                }
            };
        }

        // The notifier thread is a daemon just loops forever to wake
        // up threads in Operation.WAIT
        Thread notifier = new Thread("Notifier") {
            public void run() {
                while (true) {
                    synchronized (lock) {
                        lock.notifyAll();
                    }
                }
            }
        };
        notifier.setDaemon(true);
        notifier.start();

        for (int r = 0; r < runners.length; r++) {
            runners[r].start();
        }
        for (int r = 0; r < runners.length; r++) {
            runners[r].join();
        }
    }

    private final Operation[] operations;
    private final Object lock;
    private final int id;

    private int nextOperation;

    private ThreadStress(Object lock, int id, Operation[] operations) {
        this.lock = lock;
        this.id = id;
        this.operations = operations;
    }

    public void run() {
        try {
            if (DEBUG) {
                System.out.println("Starting ThreadStress " + id);
            }
            while (nextOperation < operations.length) {
                Operation operation = operations[nextOperation];
                if (DEBUG) {
                    System.out.println("ThreadStress " + id
                                       + " operation " + nextOperation
                                       + " is " + operation);
                }
                nextOperation++;
                switch (operation) {
                    case EXIT: {
                        return;
                    }
                    case SIGQUIT: {
                        try {
                            Os.kill(Os.getpid(), OsConstants.SIGQUIT);
                        } catch (ErrnoException ex) {
                        }
                    }
                    case SLEEP: {
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException ignored) {
                        }
                    }
                    case TIMED_WAIT: {
                        synchronized (lock) {
                            try {
                                lock.wait(100, 0);
                            } catch (InterruptedException ignored) {
                            }
                        }
                        break;
                    }
                    case WAIT: {
                        synchronized (lock) {
                            try {
                                lock.wait();
                            } catch (InterruptedException ignored) {
                            }
                        }
                        break;
                    }
                    case OOM: {
                        try {
                            List<byte[]> l = new ArrayList<byte[]>();
                            while (true) {
                                l.add(new byte[1024]);
                            }
                        } catch (OutOfMemoryError e) {
                        }
                        break;
                    }
                    case ALLOC: {
                        try {
                            List<byte[]> l = new ArrayList<byte[]>();
                            for (int i = 0; i < 1024; i++) {
                                l.add(new byte[1024]);
                            }
                        } catch (OutOfMemoryError e) {
                        }
                        break;
                    }
                    case STACKTRACE: {
                        Thread.currentThread().getStackTrace();
                        break;
                    }
                    default: {
                        throw new AssertionError(operation.toString());
                    }
                }
            }
        } finally {
            if (DEBUG) {
                System.out.println("Finishing ThreadStress for " + id);
            }
        }
    }
}
