LFMultiThreadCachingTest.java revision 11009:fdea482eec4a
1/*
2 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/*
25 * @test LFMultiThreadCachingTest
26 * @bug 8046703
27 * @summary Test verifies that lambda forms are cached when run with multiple threads
28 * @author kshefov
29 * @library /lib/testlibrary/jsr292 /lib/testlibrary
30 * @build TestMethods
31 * @build LambdaFormTestCase
32 * @build LFCachingTestCase
33 * @build LFMultiThreadCachingTest
34 * @run main/othervm/timeout=300 LFMultiThreadCachingTest
35 */
36
37import java.lang.invoke.MethodHandle;
38import java.util.EnumSet;
39import java.util.Map;
40import java.util.concurrent.BrokenBarrierException;
41import java.util.concurrent.ConcurrentLinkedQueue;
42import java.util.concurrent.CountDownLatch;
43import java.util.concurrent.CyclicBarrier;
44
45/**
46 * Multiple threaded lambda forms caching test class.
47 */
48public final class LFMultiThreadCachingTest extends LFCachingTestCase {
49    private static final TestMethods.Kind[] KINDS;
50    static {
51        EnumSet<TestMethods.Kind> set = EnumSet.complementOf(EnumSet.of(TestMethods.Kind.EXCEPT));
52        KINDS = set.toArray(new TestMethods.Kind[set.size()]);
53        if (KINDS.length < 2) {
54            throw new Error("TESTBUG: KINDS.length[" + KINDS.length + "] should be at least 2");
55        }
56    }
57    private static final int CORES = Math.max(KINDS.length, Runtime.getRuntime().availableProcessors());
58
59    /**
60     * Constructor a for multiple threaded lambda forms caching test case.
61     *
62     * @param testMethod A method from {@code j.l.i.MethodHandles} class that
63     * returns a {@code j.l.i.MethodHandle} instance.
64     */
65    public LFMultiThreadCachingTest(TestMethods testMethod) {
66        super(testMethod);
67    }
68
69    @Override
70    public void doTest() {
71        Map<String, Object> data = getTestMethod().getTestCaseData();
72        ConcurrentLinkedQueue<MethodHandle> adapters = new ConcurrentLinkedQueue<>();
73        CyclicBarrier begin = new CyclicBarrier(CORES);
74        CountDownLatch end = new CountDownLatch(CORES);
75        for (int i = 0; i < CORES; ++i) {
76            TestMethods.Kind kind = KINDS[i % KINDS.length];
77            new Thread(() -> {
78                try {
79                    begin.await();
80                    adapters.add(getTestMethod().getTestCaseMH(data, kind));
81                } catch (InterruptedException | BrokenBarrierException | IllegalAccessException | NoSuchMethodException ex) {
82                    throw new Error("Unexpected exception: ", ex);
83                } finally {
84                    end.countDown();
85                }
86            }).start();
87        }
88        try {
89            end.await();
90        } catch (InterruptedException ex) {
91            throw new Error("Unexpected exception: ", ex);
92        }
93        if (adapters.size() < CORES) {
94            throw new Error("adapters size[" + adapters.size() + "] is less than " + CORES);
95        }
96        MethodHandle prev = adapters.poll();
97        for (MethodHandle current : adapters) {
98            checkLFCaching(prev, current);
99            prev = current;
100        }
101    }
102
103    /**
104     * Main routine for multiple threaded lambda forms caching test.
105     *
106     * @param args Accepts no arguments.
107     */
108    public static void main(String[] args) {
109        LambdaFormTestCase.runTests(LFMultiThreadCachingTest::new, EnumSet.allOf(TestMethods.class));
110    }
111}
112