1 /*
2  * Copyright (c) 2001, 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 package nsk.jdi.LocatableEvent.thread;
25 
26 import nsk.share.*;
27 import nsk.share.jpda.*;
28 import nsk.share.jdi.*;
29 
30 /**
31  * This class is used as debuggee application for the thread001 JDI test.
32  */
33 
34 public class thread001a {
35 
36     //----------------------------------------------------- templete section
37 
38     static final int PASSED = 0;
39     static final int FAILED = 2;
40     static final int PASS_BASE = 95;
41 
42     static ArgumentHandler argHandler;
43     static Log log;
44 
45     //--------------------------------------------------   log procedures
46 
log1(String message)47     private static void log1(String message) {
48         log.display("**> debuggee: " + message);
49     }
50 
logErr(String message)51     private static void logErr(String message) {
52         log.complain("**> debuggee: " + message);
53     }
54 
55     //====================================================== test program
56 
57     static TestClass tcObject = new TestClass();
58 
59     static String threadNames[] = {
60                "awThread",  "mwThread",  "bpThread", "excThread",
61                "menThread", "mexThread", "stThread"
62                };
63 
64     static int threadsN = threadNames.length;
65 
66     static Thread threads[] = new Thread[threadsN];
67 
68     //------------------------------------------------------ common section
69 
70     static int exitCode = PASSED;
71 
72     static int instruction = 1;
73     static int end         = 0;
74                                    //    static int quit        = 0;
75                                    //    static int continue    = 2;
76     static int maxInstr    = 1;    // 2;
77 
78     static int lineForComm = 2;
79 
methodForCommunication()80     private static void methodForCommunication() {
81         int i1 = instruction;
82         int i2 = i1;
83         int i3 = i2;
84     }
85     //----------------------------------------------------   main method
86 
main(String argv[])87     public static void main (String argv[]) {
88 
89         argHandler = new ArgumentHandler(argv);
90         log = argHandler.createDebugeeLog();
91 
92         log1("debuggee started!");
93 
94         label0:
95             for (int i = 0; ; i++) {
96 
97                 if (instruction > maxInstr) {
98                     logErr("ERROR: unexpected instruction: " + instruction);
99                     exitCode = FAILED;
100                     break ;
101                 }
102 
103                 switch (i) {
104 
105     //------------------------------------------------------  section tested
106 
107                     case 0:
108                           for (int n1 = 0; n1 < threadsN; n1++) {
109                               if (n1 < threadsN-1)
110                                   threads[n1] =  new Thread1thread001a(threadNames[n1]);
111                               else
112                                   threads[n1] =  new Thread2thread001a(threadNames[n1]);
113                           }
114                           log1("       threads has been created");
115 
116                           synchronized (lockingObject2) {
117                               log1("      loop: threadStart(threads[n2])");
118                               for (int n2 = 0; n2 < threadsN; n2++)
119                                   if ( threadStart(threads[n2]) != PASSED )
120                                       break label0;
121 
122                               log1("      methodForCommunication();");
123                               methodForCommunication();
124                           }
125 
126                           for (int n2 = 0; n2 < threadsN; n2++) {
127                               synchronized (locks[n2]) {
128                                   log1("      synchronized (locks[n2]) : n2 == " + n2);
129                               }
130                           }
131 
132                           methodForCommunication();
133                           break ;
134 
135     //-------------------------------------------------    standard end section
136 
137                     default:
138                                 instruction = end;
139                                 methodForCommunication();
140                                 break label0;
141                 }
142             }
143 
144         System.exit(exitCode + PASS_BASE);
145     }
146 
147 
148     static Object waitnotifyObj = new Object();
149     static Object lockingObject = new Object();
150 
threadStart(Thread t)151     static int threadStart(Thread t) {
152         synchronized (waitnotifyObj) {
153             t.start();
154             try {
155 //                log3("threadStart  before:   waitnotifyObj.wait();");
156                 waitnotifyObj.wait();
157 //                log3("threadStart  after:    waitnotifyObj.wait();");
158             } catch ( Exception e) {
159                 exitCode = FAILED;
160                 logErr("       Exception : " + e );
161                 return FAILED;
162             }
163         }
164         return PASSED;
165     }
166 
167 
nullMethod()168     public static void nullMethod() {
169         throw new NullPointerException("test");
170     }
171 
172     static Object lockingObject2 = new Object();
173     static Object locks[]        = new Object[threadsN];
174 
175     static volatile int n = 0;
176 
177     static class Thread1thread001a extends Thread {
178 
179         int threadIndex;
180 
Thread1thread001a(String threadName)181         public Thread1thread001a(String threadName) {
182             super(threadName);
183             threadIndex = n;
184             locks[threadIndex] = new Object();
185             n++;
186         }
187 
run()188         public void run() {
189             log3("  'run': enter  :: threadIndex == " + threadIndex);
190 
191             synchronized (locks[threadIndex]) {
192                 log3("enter synchronized (locks[threadIndex]) ::  threadIndex == " + threadIndex);
193                 synchronized (waitnotifyObj) {
194                     waitnotifyObj.notify();
195                 }
196                 log3("  'run': exit  synchronized (waitnotifyObj)");
197 
198                 synchronized (lockingObject2) {
199                     TestClass.method();
200                 }
201                 log3("exit  synchronized (locks[threadIndex]) ::  threadIndex == " + threadIndex);
202             }
203             return;
204         }
205 
206     }
207 
208     static class Thread2thread001a extends Thread {
209 
210         int threadIndex;
211 
Thread2thread001a(String threadName)212         public Thread2thread001a(String threadName) {
213             super(threadName);
214             threadIndex = n;
215             locks[threadIndex] = new Object();
216             n++;
217         }
218 
run()219         public void run() {
220             log3("  'run': enter  :: threadIndex == " + threadIndex);
221 
222             synchronized (locks[threadIndex]) {
223                 log3("enter synchronized (locks[threadIndex]) ::  threadIndex == " + threadIndex);
224                 synchronized (waitnotifyObj) {
225                     waitnotifyObj.notify();
226                 }
227                 m1();
228                 log3("exit  synchronized (locks[threadIndex]) ::  threadIndex == " + threadIndex);
229             }
230             return;
231         }
232 
m1()233         private void m1() {
234             synchronized (lockingObject2) {
235                 log3("  'm1': enter");
236 
237                 log3("  'm1': exit");
238             }
239         }
240 
241     }
242 
243 
log3(String str)244     public static void log3(String str) {
245         log1(Thread.currentThread().getName() + " : " + str);
246     }
247 
248 }
249 
250 class TestClass {
251 
252     static int breakpointLine = 3;
253     static String awFieldName = "var1";
254     static String mwFieldName = "var2";
255 
256     static int var1 = 0;
257     static int var2 = 0;
258     static int var3 = 0;
259 
method()260     static void method () {
261         var1 += 1;
262         var3 += 1;
263         var2  = var3;
264         try {
265             thread001a.nullMethod();
266         } catch ( NullPointerException e ) {
267             thread001a.log3("  NullPointerException : " + e);
268         }
269     }
270 }
271