Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/OwnedMonitorsDebuggee.java
41161 views
/*1* Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/22package nsk.share.jdi;2324import java.io.*;25import java.util.*;26import nsk.share.locks.LockingThread;27import nsk.share.TestBug;2829/*30* Class is used as base debuggee in tests for ThreadReference.ownedMonitorsAndFrames().31*32* Class handle commands for creating threads which acquires and relinquish locks in different ways,33* nsk.share.locks.LockingThread is used for this purposes.34*35* Information about acquired monitors can be stored in static array 'monitorsInfo' and in this way this36* data is available for debugger.37*/38public class OwnedMonitorsDebuggee extends AbstractJDIDebuggee {39// command:threadName:stackFrameDescription40public static final String COMMAND_CREATE_LOCKING_THREAD = "createLockingThread";4142// command:threadName43public static final String COMMAND_STOP_LOCKING_THREAD = "stopLockingThread";4445// command:threadName46public static final String COMMAND_UPDATE_MONITOR_INFO = "updateMonitorInfo";4748// command:threadName49public static final String COMMAND_EXIT_SINGLE_FRAME = "exitSingleFrame";5051// command:threadName:monitorIndex52public static final String COMMAND_RELINQUISH_MONITOR = "relinquishMonitor";5354// command:threadName55public static final String COMMAND_ACQUIRE_RELINQUISHED_MONITOR = "acquireRelinquishedMonitor";5657// from this array information about acquired monitors is available for debugger58// (this class is used in stress tests where several tests are executed consecutively, but in this case using of59// static array shouldn't cause problems because of before using of array 'monitorsInfo' debugger60// uses COMMAND_UPDATE_MONITOR_INFO which updates this array with latest data, so excution of one test shouldn't61// affect other tests)62public static LockingThread.DebugMonitorInfo monitorsInfo[];6364private boolean returnJNIMonitors;6566public final static String mainThreadName = "OwnedMonitorDebuggeeMainThread";6768protected String[] doInit(String[] args) {69Thread.currentThread().setName(mainThreadName);7071args = super.doInit(args);7273ArrayList<String> standardArgs = new ArrayList<String>();7475for (int i = 0; i < args.length; i++) {76if (args[i].equalsIgnoreCase("-returnJNIMonitors")) {77returnJNIMonitors = true;78} else79standardArgs.add(args[i]);80}8182return standardArgs.toArray(new String[] {});83}8485public boolean parseCommand(String command) {86if (super.parseCommand(command))87return true;8889StreamTokenizer tokenizer = new StreamTokenizer(new StringReader(command));90tokenizer.whitespaceChars(':', ':');91tokenizer.wordChars('_', '_');9293try {94if (command.startsWith(COMMAND_ACQUIRE_RELINQUISHED_MONITOR)) {95tokenizer.nextToken();9697if (tokenizer.nextToken() != StreamTokenizer.TT_WORD)98throw new TestBug("Invalid command format: " + command);99100String threadName = tokenizer.sval;101102acquireRelinquishMonitor(threadName);103104return true;105} else if (command.startsWith(COMMAND_RELINQUISH_MONITOR)) {106tokenizer.nextToken();107108if (tokenizer.nextToken() != StreamTokenizer.TT_WORD)109throw new TestBug("Invalid command format: " + command);110111String threadName = tokenizer.sval;112113if (tokenizer.nextToken() != StreamTokenizer.TT_NUMBER)114throw new TestBug("Invalid command format: " + command);115116int monitorIndex = (int) tokenizer.nval;117118relinquishMonitor(threadName, monitorIndex);119120return true;121} else if (command.startsWith(COMMAND_CREATE_LOCKING_THREAD)) {122tokenizer.nextToken();123124if (tokenizer.nextToken() != StreamTokenizer.TT_WORD)125throw new TestBug("Invalid command format: " + command);126127String threadName = tokenizer.sval;128129List<String> stackFramesDescription = new ArrayList<String>();130131while (tokenizer.nextToken() == StreamTokenizer.TT_WORD) {132stackFramesDescription.add(tokenizer.sval);133}134135createLockingThread(threadName, stackFramesDescription);136return true;137} else if (command.startsWith(COMMAND_STOP_LOCKING_THREAD)) {138tokenizer.nextToken();139140if (tokenizer.nextToken() != StreamTokenizer.TT_WORD)141throw new TestBug("Invalid command format: " + command);142143String threadName = tokenizer.sval;144145stopLockingThread(threadName);146147return true;148} else if (command.startsWith(COMMAND_UPDATE_MONITOR_INFO)) {149tokenizer.nextToken();150151if (tokenizer.nextToken() != StreamTokenizer.TT_WORD)152throw new TestBug("Invalid command format: " + command);153154String threadName = tokenizer.sval;155156updateMonitorInfo(threadName);157158return true;159} else if (command.startsWith(COMMAND_EXIT_SINGLE_FRAME)) {160tokenizer.nextToken();161162if (tokenizer.nextToken() != StreamTokenizer.TT_WORD)163throw new TestBug("Invalid command format: " + command);164165String threadName = tokenizer.sval;166167exitSingleFrame(threadName);168169return true;170}171} catch (IOException e) {172throw new TestBug("Invalid command format: " + command);173}174175return false;176}177178public void acquireRelinquishMonitor(String threadName) {179LockingThread thread = getThread(threadName);180thread.acquireRelinquishedMonitor();181182thread.waitState();183updateMonitorInfo(threadName);184}185186public void relinquishMonitor(String threadName, int monitorIndex) {187LockingThread thread = getThread(threadName);188thread.relinquishMonitor(monitorIndex);189190thread.waitState();191updateMonitorInfo(threadName);192}193194private void updateMonitorInfo(String threadName) {195LockingThread thread = getThread(threadName);196monitorsInfo = thread.getMonitorsInfo(returnJNIMonitors);197}198199private Map<String, LockingThread> threads = new TreeMap<String, LockingThread>();200201private LockingThread getThread(String threadName) {202LockingThread thread = threads.get(threadName);203204if (thread == null)205throw new TestBug("Locking thread with name: " + threadName + " was not created");206207return thread;208}209210private void stopLockingThread(String threadName) {211LockingThread thread = getThread(threadName);212thread.stopLockingThread();213thread.waitState();214215updateMonitorInfo(threadName);216}217218private void exitSingleFrame(String threadName) {219LockingThread thread = getThread(threadName);220thread.exitSingleFrame();221thread.waitState();222223updateMonitorInfo(threadName);224}225226private void createLockingThread(String threadName, List<String> stackFramesDescription) {227if (threads.get(threadName) != null)228throw new TestBug("Locking thread with name: " + threadName + " already exists");229230LockingThread thread = new LockingThread(log, stackFramesDescription);231thread.setName(threadName);232thread.start();233thread.waitState();234235threads.put(threadName, thread);236237updateMonitorInfo(threadName);238}239240public static void main(String args[]) {241OwnedMonitorsDebuggee debuggee = new OwnedMonitorsDebuggee();242debuggee.doTest(args);243}244245}246247248