Test1917.java revision 4013595d91898c5a18fbc480cbd4023c4307ec62
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 while (!sem_wait.hasQueuedThreads()) {} 55 } 56 57 public void wakeupOtherThread() throws Exception { 58 sem_wait.release(); 59 } 60 } 61 62 public static class StackTraceGenerator implements Runnable { 63 private final Thread thr; 64 private final Consumer<StackTrace.StackFrameData> con; 65 public StackTraceGenerator(Thread thr, Consumer<StackTrace.StackFrameData> con) { 66 this.thr = thr; 67 this.con = con; 68 } 69 70 public StackTraceGenerator(Consumer<StackTrace.StackFrameData> con) { 71 this(null, con); 72 } 73 74 public Thread getThread() { 75 if (thr == null) { 76 return Thread.currentThread(); 77 } else { 78 return thr; 79 } 80 } 81 public void run() { 82 for (StackTrace.StackFrameData s : StackTrace.GetStackTrace(getThread())) { 83 con.accept(s); 84 } 85 } 86 } 87 88 public static class RecurCount implements Runnable { 89 private final int cnt; 90 private final Runnable then; 91 public RecurCount(int cnt, Runnable then) { 92 this.cnt = cnt; 93 this.then = then; 94 } 95 96 public void run() { 97 doRecur(0); 98 } 99 100 public void doRecur(int n) { 101 if (n < cnt) { 102 doRecur(n + 1); 103 } else { 104 then.run(); 105 } 106 } 107 } 108 109 public static Consumer<StackTrace.StackFrameData> makePrintStackFramesConsumer() 110 throws Exception { 111 final Method end_method = Test1917.class.getDeclaredMethod("run"); 112 return new Consumer<StackTrace.StackFrameData>() { 113 public void accept(StackTrace.StackFrameData data) { 114 if (TEST_PRINT_ALL) { 115 System.out.println(data); 116 } else { 117 Package p = data.method.getDeclaringClass().getPackage(); 118 // Filter out anything to do with the testing harness. 119 if (p != null && p.equals(Test1917.class.getPackage())) { 120 System.out.printf("'%s' line: %d\n", 121 data.method, 122 Breakpoint.locationToLine(data.method, data.current_location)); 123 } else if (data.method.getDeclaringClass().equals(Semaphore.class)) { 124 System.out.printf("'%s' line: <NOT-DETERMINISTIC>\n", data.method); 125 } 126 } 127 } 128 }; 129 } 130 131 public static void run() throws Exception { 132 System.out.println("Recurring 5 times"); 133 new RecurCount(5, new StackTraceGenerator(makePrintStackFramesConsumer())).run(); 134 135 System.out.println("Recurring 5 times on another thread"); 136 Thread thr = new Thread( 137 new RecurCount(5, new StackTraceGenerator(makePrintStackFramesConsumer()))); 138 thr.start(); 139 thr.join(); 140 141 System.out.println("Recurring 5 times on another thread. Stack trace from main thread!"); 142 ThreadPauser pause = new ThreadPauser(); 143 Thread thr2 = new Thread(new RecurCount(5, pause)); 144 thr2.start(); 145 pause.waitForOtherThreadToPause(); 146 new StackTraceGenerator(thr2, makePrintStackFramesConsumer()).run(); 147 pause.wakeupOtherThread(); 148 thr2.join(); 149 } 150} 151