/*
 * Copyright 2003-2005 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

/*
 * @test
 * @bug     4530538
 * @summary Basic unit test of the synchronization statistics support:
 *
 * @author  Mandy Chung
 *
 * @ignore  6309226
 * @build Semaphore
 * @run main SynchronizationStatistics
 */

import java.lang.management.*;

public class SynchronizationStatistics {
    private static ThreadMXBean mbean = ManagementFactory.getThreadMXBean();

    private static boolean blockedTimeCheck =
        mbean.isThreadContentionMonitoringSupported();
    private static boolean trace = false;

    private static Object lockA = new Object();
    private static Object lockB = new Object();
    private static Object lockC = new Object();
    private static Object lockD = new Object();
    private static Object waiter = new Object();
    private static volatile boolean testFailed = false;

    private static Object go = new Object();

    private static void goSleep(long ms) {
        try {
            Thread.sleep(ms);
        } catch (InterruptedException e) {
            e.printStackTrace();
            System.out.println("Unexpected exception.");
            testFailed = true;
        }
    }

    public static void main(String args[]) throws Exception {
        if (args.length > 0 && args[0].equals("trace")) {
            trace = true;
        }

        if (blockedTimeCheck) {
            mbean.setThreadContentionMonitoringEnabled(true);
        }

        if (!mbean.isThreadContentionMonitoringEnabled()) {
            throw new RuntimeException("TEST FAILED: " +
                "Thread Contention Monitoring is not enabled");
        }

        Examiner examiner = new Examiner("Examiner");
        BlockedThread blocked = new BlockedThread("BlockedThread");
        examiner.setThread(blocked);

        // Start the threads and check them in  Blocked and Waiting states
        examiner.start();

        // wait until the examiner acquires all the locks and waiting
        // for the BlockedThread to start
        examiner.waitUntilWaiting();

        System.out.println("Checking the thread state for the examiner thread " +
                           "is waiting to begin.");

        // The Examiner should be waiting to be notified by the BlockedThread
        checkThreadState(examiner, Thread.State.WAITING);

        System.out.println("Now starting the blocked thread");
        blocked.start();

        try {
            examiner.join();
            blocked.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
            System.out.println("Unexpected exception.");
            testFailed = true;
        }

        if (testFailed)
            throw new RuntimeException("TEST FAILED.");

        System.out.println("Test passed.");
    }

    private static String INDENT = "    ";
    private static void printStack(Thread t, StackTraceElement[] stack) {
        System.out.println(INDENT +  t +
                           " stack: (length = " + stack.length + ")");
        if (t != null) {
            for (int j = 0; j < stack.length; j++) {
                System.out.println(INDENT + stack[j]);
            }
            System.out.println();
        }
    }

    private static void checkThreadState(Thread thread, Thread.State s)
        throws Exception {

        ThreadInfo ti = mbean.getThreadInfo(thread.getId());
        if (ti.getThreadState() != s) {
            ThreadInfo info = mbean.getThreadInfo(thread.getId(),
                                                  Integer.MAX_VALUE);
            System.out.println(INDENT + "TEST FAILED:");
            printStack(thread, info.getStackTrace());
            System.out.println(INDENT + "Thread state: " + info.getThreadState());

            throw new RuntimeException("TEST FAILED: " +
                "Thread state for " + thread + " returns " + ti.getThreadState() +
                ".  Expected to be " + s);
        }
    }

    private static void checkThreadState(Thread thread,
                                         Thread.State s1, Thread.State s2)
        throws Exception {

        ThreadInfo ti = mbean.getThreadInfo(thread.getId());
        if (ti.getThreadState() != s1 && ti.getThreadState() != s2) {
            throw new RuntimeException("TEST FAILED: " +
                "Thread state for " + thread + " returns " + ti.getThreadState() +
                ".  Expected to be " + s1 + " or " + s2);
        }
    }

    static class StatThread extends Thread {
        private long blockingBaseTime = 0;
        private long totalWaitTime = 0;
        private long totalBlockedEnterTime = 0;

        StatThread(String name) {
            super(name);
        }

        void addWaitTime(long ns) {
            totalWaitTime = totalWaitTime + ns;
        }
        void addBlockedEnterTime(long ns) {
            totalBlockedEnterTime = totalBlockedEnterTime + ns;
        }
        void setBlockingBaseTime(long time) {
            blockingBaseTime = time;
        }

        long totalBlockedTimeMs() {
            return totalBlockedEnterTime / 1000000;
        }

        long totalBlockedTimeMs(long now) {
            long t = totalBlockedEnterTime + (now - blockingBaseTime);
            return t / 1000000;
        }

        long totalWaitTimeMs() {
            return totalWaitTime / 1000000;
        }

        long totalWaitTimeMs(long now) {
            long t = totalWaitTime + (now - blockingBaseTime);
            return t / 1000000;
        }
    }

    static class BlockedThread extends StatThread {
        private Semaphore handshake = new Semaphore();
        BlockedThread(String name) {
            super(name);
        }
        void waitUntilBlocked() {
            handshake.semaP();

            // give a chance for the examiner thread to really wait
            goSleep(20);
        }

        void waitUntilWaiting() {
            waitUntilBlocked();
        }

        boolean hasWaitersForBlocked() {
            return (handshake.getWaiterCount() > 0);
        }

        private void notifyWaiter() {
            // wait until the examiner waits on the semaphore
            while (handshake.getWaiterCount() == 0) {
                goSleep(20);
            }
            handshake.semaV();
        }

        private void waitObj(long ms) {
            synchronized (waiter) {
                try {
                    // notify examinerabout to wait on a monitor
                    notifyWaiter();

                    long base = System.nanoTime();
                    setBlockingBaseTime(base);
                    waiter.wait(ms);
                    long now = System.nanoTime();
                    addWaitTime(now - base);
                } catch (Exception e) {
                    e.printStackTrace();
                    System.out.println("Unexpected exception.");
                    testFailed = true;
                }
            }
        }

        private void test() {
            // notify examiner about to block on lockA
            notifyWaiter();

            long base = System.nanoTime();
            setBlockingBaseTime(base);
            synchronized (lockA) {
                long now = System.nanoTime();
                addBlockedEnterTime(now - base);

                A(); // Expected blocked count = 1
            }
            E();
        }
        private void A() {
            // notify examiner about to block on lockB
            notifyWaiter();

            long base = System.nanoTime();
            setBlockingBaseTime(base);
            synchronized (lockB) {
                long now = System.nanoTime();
                addBlockedEnterTime(now - base);

                B(); // Expected blocked count = 2
            }
        }
        private void B() {
            // notify examiner about to block on lockC
            notifyWaiter();

            long base = System.nanoTime();
            setBlockingBaseTime(base);
            synchronized (lockC) {
                long now = System.nanoTime();
                addBlockedEnterTime(now - base);

                C();  // Expected blocked count = 3
            }
        }
        private void C() {
            // notify examiner about to block on lockD
            notifyWaiter();

            long base = System.nanoTime();
            setBlockingBaseTime(base);
            synchronized (lockD) {
                long now = System.nanoTime();
                addBlockedEnterTime(now - base);

                D();  // Expected blocked count = 4
            }
        }
        private void D() {
            goSleep(50);
        }
        private void E() {
            final int WAIT = 1000;
            waitObj(WAIT);
            waitObj(WAIT);
            waitObj(WAIT);
        }

        public void run() {
            test();
        } // run()
    } // BlockedThread

    static int blockedCount = 0;
    static int waitedCount = 0;
    static class Examiner extends StatThread {
        private BlockedThread blockedThread;
        private Semaphore semaphore = new Semaphore();

        Examiner(String name) {
            super(name);
        }

        public void setThread(BlockedThread thread) {
            blockedThread = thread;
        }

        private void blockedTimeRangeCheck(StatThread t,
                                           long blockedTime,
                                           long nowNano)
            throws Exception {
            long expected = t.totalBlockedTimeMs(nowNano);

            // accept 5% range
            timeRangeCheck(blockedTime, expected, 5);
        }
        private void waitedTimeRangeCheck(StatThread t,
                                          long waitedTime,
                                          long nowNano)
            throws Exception {
            long expected = t.totalWaitTimeMs(nowNano);

            // accept 5% range
            timeRangeCheck(waitedTime, expected, 5);
        }

        private void timeRangeCheck(long time, long expected, int percent)
            throws Exception {

            double diff = expected - time;

            if (trace) {
                 System.out.println("  Time = " + time +
                    " expected = " + expected +
                    ".  Diff = " + diff);

            }
            // throw an exception if blockedTime and expectedTime
            // differs > percent%
            if (diff < 0) {
                diff = diff * -1;
            }

            long range = (expected * percent) / 100;
            // minimum range = 2 ms
            if (range < 2) {
                range = 2;
            }
            if (diff > range) {
                throw new RuntimeException("TEST FAILED: " +
                    "Time returned = " + time +
                    " expected = " + expected + ".  Diff = " + diff);
            }
        }
        private void checkInfo(StatThread t, Thread.State s, Object lock,
                               String lockName, int bcount, int wcount)
            throws Exception {

            String action = "ERROR";
            if (s == Thread.State.WAITING || s == Thread.State.TIMED_WAITING) {
                action = "wait on ";
            } else if (s == Thread.State.BLOCKED) {
                action = "block on ";
            }
            System.out.println(t + " expected to " + action + lockName +
                " with blocked count = " + bcount +
                " and waited count = " + wcount);

            long now = System.nanoTime();
            ThreadInfo info = mbean.getThreadInfo(t.getId());
            if (info.getThreadState() != s) {
                printStack(t, info.getStackTrace());
                throw new RuntimeException("TEST FAILED: " +
                    "Thread state returned is " + info.getThreadState() +
                    ". Expected to be " + s);
            }

            if (info.getLockName() == null ||
                !info.getLockName().equals(lock.toString())) {
                throw new RuntimeException("TEST FAILED: " +
                    "getLockName() returned " + info.getLockName() +
                    ". Expected to be " + lockName + " - "  + lock.toString());
            }

            if (info.getBlockedCount() != bcount) {
                throw new RuntimeException("TEST FAILED: " +
                    "Blocked Count returned is " + info.getBlockedCount() +
                    ". Expected to be " + bcount);
            }
            if (info.getWaitedCount() != wcount) {
                throw new RuntimeException("TEST FAILED: " +
                    "Waited Count returned is " + info.getWaitedCount() +
                    ". Expected to be " + wcount);
            }

            String lockObj = info.getLockName();
            if (lockObj == null || !lockObj.equals(lock.toString())) {
                throw new RuntimeException("TEST FAILED: " +
                    "Object blocked on is " + lockObj  +
                    ". Expected to be " + lock.toString());
            }

            if (!blockedTimeCheck) {
                return;
            }
            long blockedTime = info.getBlockedTime();
            if (blockedTime < 0) {
                throw new RuntimeException("TEST FAILED: " +
                    "Blocked time returned is negative = " + blockedTime);
            }

            if (s == Thread.State.BLOCKED) {
                blockedTimeRangeCheck(t, blockedTime, now);
            } else {
                timeRangeCheck(blockedTime, t.totalBlockedTimeMs(), 5);
            }

            long waitedTime = info.getWaitedTime();
            if (waitedTime < 0) {
                throw new RuntimeException("TEST FAILED: " +
                    "Waited time returned is negative = " + waitedTime);
            }
            if (s == Thread.State.WAITING || s == Thread.State.TIMED_WAITING) {
                waitedTimeRangeCheck(t, waitedTime, now);
            } else {
                timeRangeCheck(waitedTime, t.totalWaitTimeMs(), 5);
            }

        }

        private void examine() {
            try {
                synchronized (lockD) {
                    synchronized (lockC) {
                        synchronized (lockB) {
                            synchronized (lockA) {
                                // notify main thread to continue
                                semaphore.semaV();

                                // wait until BlockedThread has started
                                blockedThread.waitUntilBlocked();

                                blockedCount++;
                                checkInfo(blockedThread, Thread.State.BLOCKED,
                                          lockA, "lockA",
                                          blockedCount, waitedCount);
                            }

                           // wait until BlockedThread to block on lockB
                            blockedThread.waitUntilBlocked();

                            blockedCount++;
                            checkInfo(blockedThread, Thread.State.BLOCKED,
                                      lockB, "lockB",
                                      blockedCount, waitedCount);
                        }

                        // wait until BlockedThread to block on lockC
                        blockedThread.waitUntilBlocked();

                        blockedCount++;
                        checkInfo(blockedThread, Thread.State.BLOCKED,
                                  lockC, "lockC",
                                  blockedCount, waitedCount);
                    }
                    // wait until BlockedThread to block on lockD
                    blockedThread.waitUntilBlocked();
                    blockedCount++;

                    checkInfo(blockedThread, Thread.State.BLOCKED,
                              lockD, "lockD",
                              blockedCount, waitedCount);
                }

                // wait until BlockedThread about to call E()
                // BlockedThread will wait on waiter for 3 times
                blockedThread.waitUntilWaiting();

                waitedCount++;
                checkInfo(blockedThread, Thread.State.TIMED_WAITING,
                          waiter, "waiter", blockedCount, waitedCount);

                blockedThread.waitUntilWaiting();

                waitedCount++;
                checkInfo(blockedThread, Thread.State.TIMED_WAITING,
                          waiter, "waiter", blockedCount, waitedCount);

                blockedThread.waitUntilWaiting();

                waitedCount++;
                checkInfo(blockedThread, Thread.State.TIMED_WAITING,
                          waiter, "waiter", blockedCount, waitedCount);

            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("Unexpected exception.");
                testFailed = true;
            }
        }

        public void run() {
            examine();
        } // run()

        public void waitUntilWaiting() {
            semaphore.semaP();

            // wait until the examiner is waiting for
            while (!blockedThread.hasWaitersForBlocked()) {
                goSleep(50);
            }
            // give a chance for the examiner thread to really wait
            goSleep(20);

        }
    } // Examiner
}
