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.log.Log; 26 27 /** 28 * RecursiveMonitoringThread is a thread that recursively executes some 29 * methods and runs method runInside inside. The method may be implemented 30 * by subclasses. The types of methods are determined by recursionType, 31 * which may be JAVA (only java methods), NATIVE (only native 32 * methods) and MIXED (java and native methods). 33 */ 34 public abstract class RecursiveMonitoringThread extends MonitoringThread { 35 private RunType recursionType; 36 private int maxDepth; 37 private static final String[] expectedMethodsJava = { 38 "nsk.monitoring.share.thread.RecursiveMonitoringThread.recursiveMethod", 39 "nsk.monitoring.share.thread.RecursiveMonitoringThread.run" 40 }; 41 private static final String[] expectedMethodsNative = { 42 "nsk.monitoring.share.thread.RecursiveMonitoringThread.nativeRecursiveMethod", 43 "nsk.monitoring.share.thread.RecursiveMonitoringThread.run" 44 }; 45 private static final String[] expectedMethodsMixed = { 46 "nsk.monitoring.share.thread.RecursiveMonitoringThread.nativeRecursiveMethod", 47 "nsk.monitoring.share.thread.RecursiveMonitoringThread.recursiveMethod", 48 "nsk.monitoring.share.thread.RecursiveMonitoringThread.run" 49 }; 50 51 static { 52 System.loadLibrary("RecursiveMonitoringThread"); 53 } 54 RecursiveMonitoringThread(Log log, RunType recursionType, int maxDepth)55 public RecursiveMonitoringThread(Log log, RunType recursionType, int maxDepth) { 56 super(log); 57 this.recursionType = recursionType; 58 this.maxDepth = maxDepth; 59 } 60 run()61 public void run() { 62 switch (recursionType) { 63 case JAVA: 64 case MIXED: 65 recursiveMethod(maxDepth); 66 break; 67 case NATIVE: 68 nativeRecursiveMethod(maxDepth, true); 69 break; 70 } 71 } 72 recursiveMethod(int currentDepth)73 protected void recursiveMethod(int currentDepth) { 74 if (currentDepth-- > 0) { 75 switch (recursionType) { 76 case JAVA: 77 recursiveMethod(currentDepth); 78 break; 79 case MIXED: 80 nativeRecursiveMethod(currentDepth, false); 81 break; 82 } 83 } else { 84 runInside(); 85 } 86 } 87 isStackTraceElementExpected(StackTraceElement element)88 protected boolean isStackTraceElementExpected(StackTraceElement element) { 89 if (super.isStackTraceElementExpected(element)) 90 return true; 91 switch (recursionType) { 92 case JAVA: 93 return checkStackTraceElement(element, expectedMethodsJava); 94 case NATIVE: 95 return checkStackTraceElement(element, expectedMethodsNative); 96 case MIXED: 97 return checkStackTraceElement(element, expectedMethodsMixed); 98 default: 99 throw new IllegalArgumentException("Unknown recursionType: " + recursionType); 100 } 101 } 102 nativeRecursiveMethod(int currentDepth, boolean pureNative)103 protected native void nativeRecursiveMethod(int currentDepth, boolean pureNative); 104 runInside()105 protected abstract void runInside(); 106 } 107