/*******************************************************************************
 * Copyright (c) 1998, 2013 Oracle and/or its affiliates. All rights reserved.
 * This program and the accompanying materials are made available under the 
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 
 * which accompanies this distribution. 
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at 
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *     Oracle - initial API and implementation from Oracle TopLink
 ******************************************************************************/  
package org.eclipse.persistence.testing.framework;

import java.util.*;

/**
 * This test compares the concurrency of an operation defined run().
 * It compares the performance of performing the task with 1, 2, 4, and 16 threads.
 * On a single CPU machine all of the results should be similar,
 * on a multi-CPU machine the 2,4,16 should be faster if the task can be performed concurrently.
 */
public abstract class ConcurrentPerformanceComparisonTest extends PerformanceComparisonTestCase {
    public static double NUMBER_OF_CPUS = 1.1; // 0.1 for hyper-threading.
    public static int DEFAULT_THREADS = 32;
    protected int maxThreads;
    protected Exception caughtException;
    protected List workerThreads;

    public ConcurrentPerformanceComparisonTest() {
        this.maxThreads = DEFAULT_THREADS;
    }

    /**
     * Return the maximum number of threads the test should run to.
     */
    public int getMaxThreads() {
        return maxThreads;
    }

    /**
     * Set the maximum number of threads the test should run to.
     */
    public void setMaxThreads(int maxThreads) {
        this.maxThreads = maxThreads;
    }

    /**
     * Reset the iteration count.
     * This is maintained by the test to allow concurrent tests to manage the count.
     */
    public synchronized void resetIterations() {
        this.iterations = 0;
    }

    /**
     * Start 1 thread test.
     */
    public void startTest() {
        startTest(1);
    }

    /**
     * Start each worker thread.
     */
    public void startTest(int numberOfThreads) {
        caughtException = null;
        // Spawn worker threads.
        for (int index = 0; index < (numberOfThreads - 1); index++) {
            WorkerThread thread = (WorkerThread)getWorkerThreads().get(index);
            thread.resumeExecution();
        }
    }

    /**
     * Allows any test specific setup before starting the test run.
     */
    public void endTest() {
        // Suspend the worker threads,
        // suspend all no matter what number of threads was to even out performance.
        for (int index = 0; index < getMaxThreads(); index++) {
            WorkerThread thread = (WorkerThread)getWorkerThreads().get(index);
            thread.suspendExecution();
        }
        // Let workers finish.
        Thread.yield();
        // Wait for workers to finish,
        // wait all no matter what number of threads was to even out performance.
        for (int index = 0; index < getMaxThreads(); index++) {
            WorkerThread thread = (WorkerThread)getWorkerThreads().get(index);
            thread.joinExecution();
        }
    }

    public List getWorkerThreads() {
        return workerThreads;
    }

    /**
     * Start the worker threads.
     */
    public void setup() {
        int threads = 2;
        while (threads <= getMaxThreads()) {
            this.addThreadTest(threads);
            threads = threads * 2;
        }
        this.workerThreads = new ArrayList(getMaxThreads());
        for (int index = 0; index < getMaxThreads(); index++) {
            WorkerThread thread = new WorkerThread();
            this.workerThreads.add(thread);
            thread.start();
        }
    }

    /**
     * Count REPEATS runs of the run method with 1 thread.
     */
    public void test() throws Exception {
        test(1);
    }

    /**
     * Count REPEATS runs of the run method with n threads.
     */
    public void test(int numberOfThreads) throws Exception {
        if (caughtException != null) {
            throw caughtException;
        }
        runTask();
    }

    /**
     * Stop the worker threads.
     */
    public void reset() {
        // Stop the worker threads.
        for (int index = 0; index < getWorkerThreads().size(); index++) {
            WorkerThread thread = (WorkerThread)getWorkerThreads().get(index);
            thread.stopExecution();
        }
        // Let workers finish.
        Thread.yield();
        this.workerThreads = null;
    }

    /**
     * Verify the multi-threaded results are NUMBER_OF_CPU times better
     * than the single thread, allowing for the allowableDecrease.
     */
    public void verify() {
        PerformanceComparisonTestResult result = (PerformanceComparisonTestResult)getTestResult();
        for (int index = 0; index < result.percentageDifferences.size(); index++) {
            PerformanceComparisonTest test = (PerformanceComparisonTest)getTests().get(index);
            double allowable = 
                (Math.max(Math.min(NUMBER_OF_CPUS, index + 1), NUMBER_OF_CPUS) * 100) - 100 + (getAllowableDecrease() * 
                                                                                               (index + 1));
            test.setAllowableDecrease(allowable);
        }
        super.verify();
    }

    /**
     * Perform the task.
     */
    public abstract void runTask() throws Exception;

    /**
     * Spawn numberOfThreads to run the test's run method and count total number
     * of operations.
     */
    public void addThreadTest(final int numberOfThreads) {
        PerformanceComparisonTestCase test = new PerformanceComparisonTestCase() {
                public void startTest() {
                    ConcurrentPerformanceComparisonTest.this.startTest(numberOfThreads);
                }

                public void test() throws Exception {
                    ConcurrentPerformanceComparisonTest.this.test(numberOfThreads);
                }

                public void endTest() {
                    ConcurrentPerformanceComparisonTest.this.endTest();
                }
            };
        test.setName("ThreadTest:" + numberOfThreads);
        addTest(test);
    }

    /**
     * Defines the work thread.
     * A worker thread calls the run method in a loop,
     * until it is suspended.
     */
    protected class WorkerThread extends Thread {
        protected volatile boolean isSuspended = true;
        protected volatile boolean isDead = false;

        /**
         * After the next completion of the run method, suspend execution.
         * The thread is still alive, but waiting to be signaled to resumed.
         */
        public void stopExecution() {
            isDead = true;
        }

        /**
         * After the next completion of the run method, suspend execution.
         * The thread is still alive, but waiting to be signaled to resumed.
         */
        public void suspendExecution() {
            isSuspended = true;
        }

        /**
         * Wait for the thread to suspend.
         * Synchronize will wait for wait to release synchornization.
         */
        public synchronized void joinExecution() {
            if (!isSuspended) {
                throw new RuntimeException("Must suspend first");
            }
        }

        /**
         * Continue running the run method.
         */
        public synchronized void resumeExecution() {
            isSuspended = false;
            try {
                notify();
            } catch (Exception exception) {
                throw new RuntimeException(exception.getMessage());
            }
        }

        /**
         * Run the test run method in a loop until killed.
         */
        public synchronized void run() {
            try {
                while (!isDead) {
                    // Allows the thread to suspend itself when the current test is done.
                    if (isSuspended) {
                        wait();
                    }
                    ConcurrentPerformanceComparisonTest.this.runTask();
                    ConcurrentPerformanceComparisonTest.this.incrementIterations();
                }
            } catch (Exception exception) {
                ConcurrentPerformanceComparisonTest.this.caughtException = exception;
            }
        }
    }
}
