1 /*
2  * Copyright (c) 2007, 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 package nsk.monitoring.share.thread;
24 
25 import nsk.share.TestBug;
26 import nsk.share.log.Log;
27 import nsk.share.log.LogAware;
28 
29 public class StandardThreadMonitoringScenarioFactory implements ThreadMonitoringScenarioFactory, LogAware {
30         private Log log;
31         private int maxDepth;
32         private LockerThread lockerThread;
33         private final int typeCount = 7;
34         private int threadCount;
35 
StandardThreadMonitoringScenarioFactory(Log log, int maxDepth, int threadCount)36         public StandardThreadMonitoringScenarioFactory(Log log, int maxDepth, int threadCount) {
37                 setLog(log);
38                 this.maxDepth = maxDepth;
39                 this.threadCount = threadCount;
40         }
41 
getScenarioCount(int basicThreadCount)42         public int getScenarioCount(int basicThreadCount) {
43                 // This is choosen to have one scenario of each type and recursionType.
44                 basicThreadCount = Math.min(basicThreadCount, 3);
45                 return basicThreadCount * typeCount * 3;
46         }
47 
createScenarios(int count)48         public ThreadMonitoringScenario[] createScenarios(int count) {
49                 ThreadMonitoringScenario[] scenarios = new ThreadMonitoringScenario[count];
50                 for (int i = 0; i < count; ++i)
51                         scenarios[i] = createScenario(i);
52                 return scenarios;
53         }
54 
createScenario(String scenarioType)55         public ThreadMonitoringScenario createScenario(String scenarioType) {
56                 RunType recursionType = RunType.MIXED;
57                 if (scenarioType.equals("running"))
58                         return new RunningThread(log, recursionType, maxDepth);
59                 else if (scenarioType.equals("sleeping"))
60                         return new SleepingThread(log, recursionType, maxDepth);
61                 else if (scenarioType.equals("timedWaiting"))
62                         return new TimedWaitingThread(log, recursionType, maxDepth);
63                 else if (scenarioType.equals("waiting"))
64                         return new WaitingThread(log, recursionType, maxDepth);
65                 else if (scenarioType.equals("blocked"))
66                         return new BlockedThread(log, recursionType, maxDepth, getLockerThread());
67                 else if (scenarioType.equals("nativeBlocked"))
68                         return new NativeBlockedThread(log, recursionType, maxDepth, getLockerThread());
69                 else if (scenarioType.equals("new"))
70                         return new NewThread(log, recursionType, maxDepth);
71                 else if (scenarioType.equals("finished"))
72                         return new FinishedThread(log, recursionType, maxDepth);
73                 else if (scenarioType.equals("lockingThreads"))
74                         return new LockingThreads(log, recursionType, maxDepth);
75                 else if (scenarioType.equals("synchronizerLockingThreads"))
76                         return new SynchronizerLockingThreads(log, recursionType, maxDepth);
77                 else if (scenarioType.equals("javaDeadlock"))
78                         return new Deadlock(log, recursionType, maxDepth, Deadlock.Type.JAVA, threadCount);
79                 else if (scenarioType.equals("nativeDeadlock"))
80                         return new Deadlock(log, recursionType, maxDepth, Deadlock.Type.NATIVE, threadCount);
81                 else if (scenarioType.equals("synchronizedMethodDeadlock"))
82                         return new Deadlock(log, recursionType, maxDepth, Deadlock.Type.SYNCHRONIZED_METHOD, threadCount);
83                 else if (scenarioType.equals("synchronizerDeadlock"))
84                         return new Deadlock(log, recursionType, maxDepth, Deadlock.Type.SYNCHRONIZER, threadCount);
85                 else if (scenarioType.equals("mixedDeadlock"))
86                         return new Deadlock(log, recursionType, maxDepth, Deadlock.Type.MIXED, 16);
87                 /*
88                 else if (scenarioType.equals("mixedMonitorDeadlock"))
89                         return new Deadlock(log, recursionType, maxDepth, Deadlock.DeadlockType.MIXED, threadCount);
90                 else if (scenarioType.equals("mixed2MonitorDeadlock"))
91                         return new MonitorDeadlock(log, recursionType, maxDepth, MonitorDeadlock.DeadlockType.MIXED2, threadCount);
92                         */
93                 throw new TestBug("Unknown scenario type: " + scenarioType);
94         }
95 
createScenario(int i)96         protected ThreadMonitoringScenario createScenario(int i) {
97                 RunType recursionType;
98                 switch (i % 3) {
99                 case 0:
100                         recursionType = RunType.JAVA;
101                         break;
102                 case 1:
103                         recursionType = RunType.NATIVE;
104                         break;
105                 case 2:
106                         recursionType = RunType.MIXED;
107                         break;
108                 default:
109                         throw new TestBug("Unknown recursionType.");
110                 }
111                 switch (i % typeCount) {
112                 case 0:
113                         return new SleepingThread(log, recursionType, maxDepth);
114                 case 1:
115                         return new TimedWaitingThread(log, recursionType, maxDepth);
116                 case 2:
117                         return new RunningThread(log, recursionType, maxDepth);
118                 case 3:
119                         return new WaitingThread(log, recursionType, maxDepth);
120                 case 4:
121                         return new BlockedThread(log, recursionType, maxDepth, getLockerThread());
122                 case 5:
123                         return new LockingThreads(log, recursionType, maxDepth);
124                 case 6:
125                         return new SynchronizerLockingThreads(log, recursionType, maxDepth);
126                 default:
127                         throw new TestBug("Unknown thread kind");
128                 }
129         }
130 
getLockerThread()131         private LockerThread getLockerThread() {
132                 if (lockerThread == null) {
133                         lockerThread = new LockerThread();
134                         lockerThread.start();
135                         lockerThread.waitState();
136                 }
137                 return lockerThread;
138         }
139 
finish()140         public void finish() {
141                 if (lockerThread != null) {
142                         lockerThread.finish();
143                         try {
144                                 lockerThread.join();
145                         } catch (InterruptedException e) {
146                                 log.warn(e);
147                         }
148                         lockerThread = null;
149                 }
150         }
151 
setLog(Log log)152         public void setLog(Log log) {
153                 this.log = log;
154         }
155 }
156