Test1917.java revision 47d49b842a87823df6ffda30bb21bd6d8e4d8641
1/* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package art; 18 19import java.io.PrintWriter; 20import java.io.StringWriter; 21import java.lang.reflect.Executable; 22import java.lang.reflect.Method; 23import java.lang.reflect.Field; 24import java.util.ArrayList; 25import java.util.Arrays; 26import java.util.Collection; 27import java.util.HashSet; 28import java.util.List; 29import java.util.concurrent.Semaphore; 30import java.util.Vector; 31import java.util.function.Function; 32import java.util.function.Predicate; 33import java.util.function.Supplier; 34import java.util.function.Consumer; 35 36public class Test1917 { 37 public final static boolean TEST_PRINT_ALL = false; 38 39 public static class ThreadPauser implements Runnable { 40 public Semaphore sem_wakeup_main = new Semaphore(0); 41 public Semaphore sem_wait = new Semaphore(0); 42 43 public void run() { 44 try { 45 sem_wakeup_main.release(); 46 sem_wait.acquire(); 47 } catch (Exception e) { 48 throw new Error("Error with semaphores!", e); 49 } 50 } 51 52 public void waitForOtherThreadToPause() throws Exception { 53 sem_wakeup_main.acquire(); 54 } 55 56 public void wakeupOtherThread() throws Exception { 57 sem_wait.release(); 58 } 59 } 60 61 public static class StackTraceGenerator implements Runnable { 62 private final Thread thr; 63 private final Consumer<StackTrace.StackFrameData> con; 64 public StackTraceGenerator(Thread thr, Consumer<StackTrace.StackFrameData> con) { 65 this.thr = thr; 66 this.con = con; 67 } 68 69 public StackTraceGenerator(Consumer<StackTrace.StackFrameData> con) { 70 this(null, con); 71 } 72 73 public Thread getThread() { 74 if (thr == null) { 75 return Thread.currentThread(); 76 } else { 77 return thr; 78 } 79 } 80 public void run() { 81 for (StackTrace.StackFrameData s : StackTrace.GetStackTrace(getThread())) { 82 con.accept(s); 83 } 84 } 85 } 86 87 public static class RecurCount implements Runnable { 88 private final int cnt; 89 private final Runnable then; 90 public RecurCount(int cnt, Runnable then) { 91 this.cnt = cnt; 92 this.then = then; 93 } 94 95 public void run() { 96 doRecur(0); 97 } 98 99 public void doRecur(int n) { 100 if (n < cnt) { 101 doRecur(n + 1); 102 } else { 103 then.run(); 104 } 105 } 106 } 107 108 public static Consumer<StackTrace.StackFrameData> makePrintStackFramesConsumer() 109 throws Exception { 110 final Method end_method = Test1917.class.getDeclaredMethod("run"); 111 return new Consumer<StackTrace.StackFrameData>() { 112 public void accept(StackTrace.StackFrameData data) { 113 if (TEST_PRINT_ALL) { 114 System.out.println(data); 115 } else { 116 Package p = data.method.getDeclaringClass().getPackage(); 117 // Filter out anything to do with the testing harness. 118 if (p != null && p.equals(Test1917.class.getPackage())) { 119 System.out.printf("'%s' line: %d\n", 120 data.method, 121 Breakpoint.locationToLine(data.method, data.current_location)); 122 } else if (data.method.getDeclaringClass().equals(Semaphore.class)) { 123 System.out.printf("'%s' line: <NOT-DETERMINISTIC>\n", data.method); 124 } 125 } 126 } 127 }; 128 } 129 130 public static void run() throws Exception { 131 System.out.println("Recurring 5 times"); 132 new RecurCount(5, new StackTraceGenerator(makePrintStackFramesConsumer())).run(); 133 134 System.out.println("Recurring 5 times on another thread"); 135 Thread thr = new Thread( 136 new RecurCount(5, new StackTraceGenerator(makePrintStackFramesConsumer()))); 137 thr.start(); 138 thr.join(); 139 140 System.out.println("Recurring 5 times on another thread. Stack trace from main thread!"); 141 ThreadPauser pause = new ThreadPauser(); 142 Thread thr2 = new Thread(new RecurCount(5, pause)); 143 thr2.start(); 144 pause.waitForOtherThreadToPause(); 145 new StackTraceGenerator(thr2, makePrintStackFramesConsumer()).run(); 146 pause.wakeupOtherThread(); 147 thr2.join(); 148 } 149} 150