blob: 47b06cfa214a8768f459b8af0aaf50849a24961a [file] [log] [blame]
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package art;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Executable;
import java.lang.reflect.Method;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.Semaphore;
import java.util.Vector;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.function.Consumer;
public class Test1917 {
public final static boolean TEST_PRINT_ALL = false;
public static class ThreadPauser implements Runnable {
public Semaphore sem_wakeup_main = new Semaphore(0);
public Semaphore sem_wait = new Semaphore(0);
public void run() {
try {
sem_wakeup_main.release();
sem_wait.acquire();
} catch (Exception e) {
throw new Error("Error with semaphores!", e);
}
}
public void waitForOtherThreadToPause() throws Exception {
sem_wakeup_main.acquire();
while (!sem_wait.hasQueuedThreads()) {}
}
public void wakeupOtherThread() throws Exception {
sem_wait.release();
}
}
public static class StackTraceGenerator implements Runnable {
private final Thread thr;
private final Consumer<StackTrace.StackFrameData> con;
public StackTraceGenerator(Thread thr, Consumer<StackTrace.StackFrameData> con) {
this.thr = thr;
this.con = con;
}
public StackTraceGenerator(Consumer<StackTrace.StackFrameData> con) {
this(null, con);
}
public Thread getThread() {
if (thr == null) {
return Thread.currentThread();
} else {
return thr;
}
}
public void run() {
for (StackTrace.StackFrameData s : StackTrace.GetStackTrace(getThread())) {
con.accept(s);
}
}
}
public static class RecurCount implements Runnable {
private final int cnt;
private final Runnable then;
public RecurCount(int cnt, Runnable then) {
this.cnt = cnt;
this.then = then;
}
public void run() {
doRecur(0);
}
public void doRecur(int n) {
if (n < cnt) {
doRecur(n + 1);
} else {
then.run();
}
}
}
public static Consumer<StackTrace.StackFrameData> makePrintStackFramesConsumer()
throws Exception {
final Method end_method = Test1917.class.getDeclaredMethod("run");
return new Consumer<StackTrace.StackFrameData>() {
public void accept(StackTrace.StackFrameData data) {
if (TEST_PRINT_ALL) {
System.out.println(data);
} else {
Package p = data.method.getDeclaringClass().getPackage();
// Filter out anything to do with the testing harness.
if (p != null && p.equals(Test1917.class.getPackage())) {
System.out.printf("'%s' line: %d\n",
data.method,
Breakpoint.locationToLine(data.method, data.current_location));
} else if (data.method.getDeclaringClass().equals(Semaphore.class)) {
System.out.printf("'%s' line: <NOT-DETERMINISTIC>\n", data.method);
}
}
}
};
}
public static void run() throws Exception {
System.out.println("Recurring 5 times");
new RecurCount(5, new StackTraceGenerator(makePrintStackFramesConsumer())).run();
System.out.println("Recurring 5 times on another thread");
Thread thr = new Thread(
Thread.currentThread().getThreadGroup(),
new RecurCount(5, new StackTraceGenerator(makePrintStackFramesConsumer())),
"Recurring Thread 1",
10*1000000 /* 10 mb*/);
thr.start();
thr.join();
System.out.println("Recurring 5 times on another thread. Stack trace from main thread!");
ThreadPauser pause = new ThreadPauser();
Thread thr2 = new Thread(
Thread.currentThread().getThreadGroup(),
new RecurCount(5, pause),
"Recurring Thread 2",
10*1000000 /* 10 mb*/);
thr2.start();
pause.waitForOtherThreadToPause();
new StackTraceGenerator(thr2, makePrintStackFramesConsumer()).run();
pause.wakeupOtherThread();
thr2.join();
}
}