1 /*
2  * Copyright (c) 2016, 2020, 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 /*
26  * @test HandshakeWalkStackTest
27  * @library /testlibrary /test/lib
28  * @build HandshakeWalkStackTest
29  * @run driver ClassFileInstaller sun.hotspot.WhiteBox
30  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI HandshakeWalkStackTest
31  */
32 
33 import jdk.test.lib.Asserts;
34 import sun.hotspot.WhiteBox;
35 
36 public class HandshakeWalkStackTest {
37 
main(String... args)38     public static void main(String... args) throws Exception {
39         int iterations = 3;
40         if (args.length > 0) {
41             iterations = Integer.parseInt(args[0]);
42         }
43         test(iterations);
44     }
45 
test(int iterations)46     private static void test(int iterations) throws Exception {
47         Thread loop_thread  = new Thread(() -> run_loop(create_list()));
48         Thread alloc_thread = new Thread(() -> run_alloc());
49         Thread wait_thread  = new Thread(() -> run_wait(new Object() {}));
50         loop_thread.start();
51         alloc_thread.start();
52         wait_thread.start();
53 
54         WhiteBox wb = WhiteBox.getWhiteBox();
55         int walked = 0;
56         for (int i = 0; i < iterations; i++) {
57             System.out.println("Iteration " + i);
58             System.out.flush();
59             Thread.sleep(200);
60             walked = wb.handshakeWalkStack(loop_thread, false);
61             Asserts.assertEQ(walked, 1, "Must have walked one thread stack");
62             Thread.sleep(200);
63             walked = wb.handshakeWalkStack(alloc_thread, false);
64             Asserts.assertEQ(walked, 1, "Must have walked one thread stack");
65             Thread.sleep(200);
66             walked = wb.handshakeWalkStack(wait_thread, false);
67             Asserts.assertEQ(walked, 1, "Must have walked one thread stack");
68             Thread.sleep(200);
69             walked = wb.handshakeWalkStack(Thread.currentThread(), false);
70             Asserts.assertEQ(walked, 1, "Must have walked one thread stack");
71         }
72         Thread.sleep(200);
73         walked = wb.handshakeWalkStack(null, true);
74         Asserts.assertGT(walked, 4, "Must have walked more than three thread stacks");
75     }
76 
77     static class List {
78         List next;
79 
List(List next)80         List(List next) {
81             this.next = next;
82         }
83     }
84 
create_list()85     public static List create_list() {
86         List head = new List(null);
87         List elem = new List(head);
88         List elem2 = new List(elem);
89         List elem3 = new List(elem2);
90         List elem4 = new List(elem3);
91         head.next = elem4;
92 
93         return head;
94     }
95 
run_loop(List loop)96     public static void run_loop(List loop) {
97         while (loop.next != null) {
98             loop = loop.next;
99         }
100     }
101 
102     public static byte[] array;
103 
run_alloc()104     public static void run_alloc() {
105         while (true) {
106             // Write to public static to ensure the byte array escapes.
107             array = new byte[4096];
108         }
109     }
110 
run_wait(Object lock)111     public static void run_wait(Object lock) {
112         synchronized (lock) {
113             try {
114                 lock.wait();
115             } catch (InterruptedException ie) {}
116         }
117     }
118 }
119