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