/*
 * 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*
 * This file is available under and governed by the GNU General Public
 * License version 2 only, as published by the Free Software Foundation.
 * However, the following notice accompanied the original version of this
 * file:
 *
 * Written by Doug Lea with assistance from members of JCP JSR-166
 * Expert Group and released to the public domain, as explained at
 * http://creativecommons.org/licenses/publicdomain
 */

/*
 * @test
 * @bug 6785442
 * @summary Checks race between poll and remove(Object), while
 * occasionally moonlighting as a microbenchmark.
 * @run main RemovePollRace 12345
 */

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.LinkedTransferQueue;
import java.util.concurrent.atomic.AtomicLong;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Queue;
import java.util.Map;

public class RemovePollRace {
    // Suitable for benchmarking.  Overriden by args[0] for testing.
    int count = 1024 * 1024;

    final Map<String,String> results = new ConcurrentHashMap<String,String>();

    Collection<Queue<Boolean>> concurrentQueues() {
        List<Queue<Boolean>> queues = new ArrayList<Queue<Boolean>>();
        queues.add(new ConcurrentLinkedQueue<Boolean>());
        queues.add(new ArrayBlockingQueue<Boolean>(count, false));
        queues.add(new ArrayBlockingQueue<Boolean>(count, true));
        queues.add(new LinkedBlockingQueue<Boolean>());
        queues.add(new LinkedBlockingDeque<Boolean>());
        queues.add(new LinkedTransferQueue<Boolean>());

        // Following additional implementations are available from:
        // http://gee.cs.oswego.edu/dl/concurrency-interest/index.html
        // queues.add(new SynchronizedLinkedListQueue<Boolean>());

        // Avoid "first fast, second slow" benchmark effect.
        Collections.shuffle(queues);
        return queues;
    }

    void prettyPrintResults() {
        List<String> classNames = new ArrayList<String>(results.keySet());
        Collections.sort(classNames);
        int maxClassNameLength = 0;
        int maxNanosLength = 0;
        for (String name : classNames) {
            if (maxClassNameLength < name.length())
                maxClassNameLength = name.length();
            if (maxNanosLength < results.get(name).length())
                maxNanosLength = results.get(name).length();
        }
        String format = String.format("%%%ds %%%ds nanos/item%%n",
                                      maxClassNameLength, maxNanosLength);
        for (String name : classNames)
            System.out.printf(format, name, results.get(name));
    }

    void test(String[] args) throws Throwable {
        if (args.length > 0)
            count = Integer.valueOf(args[0]);
        // Warmup
        for (Queue<Boolean> queue : concurrentQueues())
            test(queue);
        results.clear();
        for (Queue<Boolean> queue : concurrentQueues())
            test(queue);

        prettyPrintResults();
    }

    void await(CountDownLatch latch) {
        try { latch.await(); }
        catch (InterruptedException e) { unexpected(e); }
    }

    void test(final Queue<Boolean> q) throws Throwable {
        long t0 = System.nanoTime();
        final int SPINS = 5;
        final AtomicLong removes = new AtomicLong(0);
        final AtomicLong polls = new AtomicLong(0);
        final int adderCount =
            Math.max(1, Runtime.getRuntime().availableProcessors() / 4);
        final int removerCount =
            Math.max(1, Runtime.getRuntime().availableProcessors() / 4);
        final int pollerCount = removerCount;
        final int threadCount = adderCount + removerCount + pollerCount;
        final CountDownLatch startingGate = new CountDownLatch(1);
        final CountDownLatch addersDone = new CountDownLatch(adderCount);
        final Runnable remover = new Runnable() {
            public void run() {
                await(startingGate);
                int spins = 0;
                for (;;) {
                    boolean quittingTime = (addersDone.getCount() == 0);
                    if (q.remove(Boolean.TRUE))
                        removes.getAndIncrement();
                    else if (quittingTime)
                        break;
                    else if (++spins > SPINS) {
                        Thread.yield();
                        spins = 0;
                    }}}};
        final Runnable poller = new Runnable() {
            public void run() {
                await(startingGate);
                int spins = 0;
                for (;;) {
                    boolean quittingTime = (addersDone.getCount() == 0);
                    if (q.poll() == Boolean.TRUE)
                        polls.getAndIncrement();
                    else if (quittingTime)
                        break;
                    else if (++spins > SPINS) {
                        Thread.yield();
                        spins = 0;
                    }}}};
        final Runnable adder = new Runnable() {
            public void run() {
                await(startingGate);
                for (int i = 0; i < count; i++) {
                    for (;;) {
                        try { q.add(Boolean.TRUE); break; }
                        catch (IllegalStateException e) { Thread.yield(); }
                    }
                }
                addersDone.countDown();
            }};

        final List<Thread> adders   = new ArrayList<Thread>();
        final List<Thread> removers = new ArrayList<Thread>();
        final List<Thread> pollers  = new ArrayList<Thread>();
        for (int i = 0; i < adderCount; i++)
            adders.add(checkedThread(adder));
        for (int i = 0; i < removerCount; i++)
            removers.add(checkedThread(remover));
        for (int i = 0; i < pollerCount; i++)
            pollers.add(checkedThread(poller));

        final List<Thread> allThreads = new ArrayList<Thread>();
        allThreads.addAll(removers);
        allThreads.addAll(pollers);
        allThreads.addAll(adders);

        for (Thread t : allThreads)
            t.start();
        startingGate.countDown();
        for (Thread t : allThreads)
            t.join();

        String className = q.getClass().getSimpleName();
        long elapsed = System.nanoTime() - t0;
        int nanos = (int) ((double) elapsed / (adderCount * count));
        results.put(className, String.valueOf(nanos));
        if (removes.get() + polls.get() != adderCount * count) {
            String msg = String.format
                ("class=%s removes=%s polls=%d count=%d",
                 className, removes.get(), polls.get(), count);
            fail(msg);
        }
    }

    //--------------------- Infrastructure ---------------------------
    volatile int passed = 0, failed = 0;
    void pass() {passed++;}
    void fail() {failed++; Thread.dumpStack();}
    void fail(String msg) {System.err.println(msg); fail();}
    void unexpected(Throwable t) {failed++; t.printStackTrace();}
    void check(boolean cond) {if (cond) pass(); else fail();}
    void equal(Object x, Object y) {
        if (x == null ? y == null : x.equals(y)) pass();
        else fail(x + " not equal to " + y);}
    public static void main(String[] args) throws Throwable {
        new RemovePollRace().instanceMain(args);}
    public void instanceMain(String[] args) throws Throwable {
        try {test(args);} catch (Throwable t) {unexpected(t);}
        System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
        if (failed > 0) throw new AssertionError("Some tests failed");}
    Thread checkedThread(final Runnable r) {
        return new Thread() {public void run() {
            try {r.run();} catch (Throwable t) {unexpected(t);}}};}
}
