test/hotspot/jtreg/runtime/handshake/HandshakeWalkStackTest.java
author rehn
Wed, 31 Oct 2018 08:09:45 +0100
changeset 52341 2b58b8e1d28f
parent 48791 6e079ff6c83c
permissions -rw-r--r--
8212933: Thread-SMR: requesting a VM operation whilst holding a ThreadsListHandle can cause deadlocks Reviewed-by: eosterlund, dcubed, sspitsyn, dholmes
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
47881
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
     1
/*
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
     2
 * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
     4
 *
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
     7
 * published by the Free Software Foundation.
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
     8
 *
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    13
 * accompanied this code).
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    14
 *
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    18
 *
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    21
 * questions.
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    22
 *
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    23
 */
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    24
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    25
/*
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    26
 * @test HandshakeWalkStackTest
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    27
 * @library /testlibrary /test/lib
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    28
 * @build HandshakeWalkStackTest
48791
6e079ff6c83c 8186635: ClassFileInstaller should be run as a driver
iignatyev
parents: 47881
diff changeset
    29
 * @run driver ClassFileInstaller sun.hotspot.WhiteBox
47881
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    30
 *                              sun.hotspot.WhiteBox$WhiteBoxPermission
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    31
 * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI HandshakeWalkStackTest
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    32
 */
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    33
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    34
import jdk.test.lib.Asserts;
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    35
import sun.hotspot.WhiteBox;
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    36
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    37
public class HandshakeWalkStackTest {
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    38
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    39
    public static void main(String... args) throws Exception {
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    40
        int iterations = 3;
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    41
        if (args.length > 0) {
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    42
            iterations = Integer.parseInt(args[0]);
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    43
        }
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    44
        test(iterations);
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    45
    }
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    46
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    47
    private static void test(int iterations) throws Exception {
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    48
        Thread loop_thread  = new Thread(() -> run_loop(create_list()));
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    49
        Thread alloc_thread = new Thread(() -> run_alloc());
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    50
        Thread wait_thread  = new Thread(() -> run_wait(new Object() {}));
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    51
        loop_thread.start();
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    52
        alloc_thread.start();
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    53
        wait_thread.start();
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    54
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    55
        WhiteBox wb = WhiteBox.getWhiteBox();
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    56
        int walked = 0;
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    57
        for (int i = 0; i < iterations; i++) {
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    58
            System.out.println("Iteration " + i);
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    59
            System.out.flush();
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    60
            Thread.sleep(200);
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    61
            walked = wb.handshakeWalkStack(loop_thread, false);
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    62
            Asserts.assertEQ(walked, 1, "Must have walked one thread stack");
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    63
            Thread.sleep(200);
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    64
            walked = wb.handshakeWalkStack(alloc_thread, false);
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    65
            Asserts.assertEQ(walked, 1, "Must have walked one thread stack");
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    66
            Thread.sleep(200);
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    67
            walked = wb.handshakeWalkStack(wait_thread, false);
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    68
            Asserts.assertEQ(walked, 1, "Must have walked one thread stack");
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    69
            Thread.sleep(200);
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    70
            walked = wb.handshakeWalkStack(Thread.currentThread(), false);
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    71
            Asserts.assertEQ(walked, 1, "Must have walked one thread stack");
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    72
        }
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    73
        Thread.sleep(200);
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    74
        walked = wb.handshakeWalkStack(null, true);
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    75
        Asserts.assertGT(walked, 4, "Must have walked more than three thread stacks");
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    76
    }
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    77
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    78
    static class List {
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    79
        List next;
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    80
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    81
        List(List next) {
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    82
            this.next = next;
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    83
        }
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    84
    }
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    85
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    86
    public static List create_list() {
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    87
        List head = new List(null);
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    88
        List elem = new List(head);
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    89
        List elem2 = new List(elem);
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    90
        List elem3 = new List(elem2);
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    91
        List elem4 = new List(elem3);
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    92
        head.next = elem4;
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    93
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    94
        return head;
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    95
    }
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    96
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    97
    public static void run_loop(List loop) {
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    98
        while (loop.next != null) {
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
    99
            loop = loop.next;
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
   100
        }
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
   101
    }
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
   102
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
   103
    public static byte[] array;
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
   104
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
   105
    public static void run_alloc() {
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
   106
        while (true) {
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
   107
            // Write to public static to ensure the byte array escapes.
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
   108
            array = new byte[4096];
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
   109
        }
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
   110
    }
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
   111
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
   112
    public static void run_wait(Object lock) {
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
   113
        synchronized (lock) {
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
   114
            try {
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
   115
                lock.wait();
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
   116
            } catch (InterruptedException ie) {}
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
   117
        }
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
   118
    }
0ce0ac68ace7 8189941: Implementation JEP 312: Thread-local handshake
rehn
parents:
diff changeset
   119
}