1 /*
2  * Copyright (c) 2010, 2018, 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
26  *
27  * @summary converted from VM Testbase jit/escape/AdaptiveBlocking/AdaptiveBlocking001.
28  * VM Testbase keywords: [jit, quick]
29  * VM Testbase readme:
30  * This is a basic JIT compiler adaptive blocking test. The test runs 2 threads
31  * contending for a shared resource. In the first round, the lock is held for
32  * a short period of time, provoking spinlock-style locking. In the second round,
33  * the lock is held for a long period of time, provoking blocked locking. The
34  * described scenario is repeated numRounds (specified by the -numRounds
35  * parameter) times.
36  *
37  * @library /vmTestbase
38  *          /test/lib
39  * @run driver jdk.test.lib.FileInstaller . .
40  * @build jit.escape.AdaptiveBlocking.AdaptiveBlocking001.AdaptiveBlocking001
41  * @run driver/timeout=300 ExecDriver --java -server -Xcomp -XX:+DoEscapeAnalysis
42  *             jit.escape.AdaptiveBlocking.AdaptiveBlocking001.AdaptiveBlocking001 -numRounds 10
43  */
44 
45 package jit.escape.AdaptiveBlocking.AdaptiveBlocking001;
46 
47 import nsk.share.TestFailure;
48 
49 class AdaptiveBlocking001
50 {
51         public static int numRounds = 10;
52 
53         private static Object sharedLock = new Object();
54         private static boolean lockEntered1;
55         private static boolean lockEntered2;
56 
57         private static boolean latentLocks;
58 
59         private static boolean done;
60 
61         private static boolean failed;
62 
main( String[] args )63         public static void main( String[] args )
64         {
65                 System.out.println( "Adaptive blocking test" );
66 
67                 parseArgs( args );
68 
69                 for( int i=0; i < numRounds; ++i )
70                 {
71                         doRound(i, false);
72                         doRound(i, true);
73                 }
74 
75                 if( !failed )
76                         System.out.println( "TEST PASSED" );
77                 else
78                         throw new TestFailure( "TEST FAILED" );
79         }
80 
parseArgs( String[] args )81         private static void parseArgs( String[] args )
82         {
83                 for( int i=0; i < args.length; ++i )
84                 {
85                         String arg = args[i];
86                         String val;
87 
88                         if( arg.equals( "-numRounds" ) )
89                         {
90                                 if( ++i < args.length )
91                                         val = args[i];
92                                 else
93                                         throw new TestFailure( "Need value for '" + arg + "' parameter" );
94 
95                                 try {
96                                         numRounds = Integer.parseInt( val );
97                                 } catch( NumberFormatException e ) {
98                                         throw new TestFailure( "Invalid value for '" + arg + "' parameter: " + val );
99                                 }
100                         }
101                         else
102                         {
103                                 throw new TestFailure( "Invalid argument: " + args );
104                         }
105                 }
106         }
107 
doRound(int ord, boolean latent_locks)108         private static void doRound(int ord, boolean latent_locks)
109         {
110                 System.out.println( "round #" + ord + ", latent locks: " + (latent_locks ? "yes" : "no") + "..." );
111 
112                 latentLocks = latent_locks;
113 
114                 Thread_1 t1 = new Thread_1();
115                 Thread_2 t2 = new Thread_2();
116 
117                 done = false;
118 
119                 t1.start();
120                 t2.start();
121 
122                 for( int i=0; i < 10; ++i )
123                 {
124                         try {
125                                 Thread.sleep( 1000 );
126                         } catch( InterruptedException e ) {
127                         }
128 
129                         if( done )
130                                 break;
131                 }
132 
133                 done = true;
134 
135                 try {
136                         t1.join();
137                         t2.join();
138                 } catch( InterruptedException e ) {
139                 }
140         }
141 
142         private static class Thread_1 extends Thread
143         {
run()144                 public void run()
145                 {
146                         while( !done )
147                         {
148                                 synchronized( sharedLock )
149                                 {
150                                         lockEntered1 = true;
151                                         if( lockEntered2 )
152                                         {
153                                                 Fail();
154                                                 done = true;
155                                                 break;
156                                         }
157 
158                                         holdLock();
159 
160                                         lockEntered1 = false;
161                                 }
162                         }
163                 }
164         }
165 
166         private static class Thread_2 extends Thread
167         {
run()168                 public void run()
169                 {
170                         while( !done )
171                         {
172                                 synchronized( sharedLock )
173                                 {
174                                         lockEntered2 = true;
175                                         if( lockEntered1 )
176                                         {
177                                                 Fail();
178                                                 done = true;
179                                                 break;
180                                         }
181 
182                                         holdLock();
183 
184                                         lockEntered2 = false;
185                                 }
186                         }
187                 }
188         }
189 
holdLock()190         private static void holdLock()
191         {
192                 if( latentLocks )
193                 {
194                         try {
195                                 Thread.sleep( 500 );
196                         } catch( InterruptedException e ) {
197                         }
198                 }
199         }
200 
Fail()201         private static void Fail()
202         {
203                 failed = true;
204         }
205 }
206