Profile.java revision 3d238a7a19b1010578709c63f86e12b2bce0e4fc
13d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang/* 23d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang * Copyright (C) 2012 The Android Open Source Project 33d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang * 43d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang * Licensed under the Apache License, Version 2.0 (the "License"); 53d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang * you may not use this file except in compliance with the License. 63d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang * You may obtain a copy of the License at 73d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang * 83d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang * http://www.apache.org/licenses/LICENSE-2.0 93d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang * 103d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang * Unless required by applicable law or agreed to in writing, software 113d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang * distributed under the License is distributed on an "AS IS" BASIS, 123d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang * See the License for the specific language governing permissions and 143d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang * limitations under the License. 153d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang */ 163d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 173d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Changpackage com.android.gallery3d.util; 183d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 193d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Changimport com.android.gallery3d.common.Utils; 203d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 213d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Changimport android.os.Handler; 223d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Changimport android.os.HandlerThread; 233d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Changimport android.os.Process; 243d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Changimport android.util.Log; 253d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 263d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Changimport java.util.ArrayList; 273d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Changimport java.util.Random; 283d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 293d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang// The Profile class is used to collect profiling information for a thread. It 303d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang// samples stack traces for a thread periodically. enable() and disable() is 313d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang// used to enable and disable profiling for the calling thread. The profiling 323d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang// information can then be dumped to a file using the dumpToFile() method. 333d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang// 343d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang// The disableAll() method can be used to disable profiling for all threads and 353d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang// can be called in onPause() to ensure all profiling is disabled when an 363d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang// activity is paused. 373d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Changpublic class Profile { 383d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang private static final String TAG = "Profile"; 393d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang private static final int NS_PER_MS = 1000000; 403d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 413d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang // This is a watchdog entry for one thread. 423d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang // For every cycleTime period, we dump the stack of the thread. 433d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang private static class WatchEntry { 443d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang Thread thread; 453d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 463d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang // Both are in milliseconds 473d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang int cycleTime; 483d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang int wakeTime; 493d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 503d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang boolean isHolding; 513d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang ArrayList<String[]> holdingStacks = new ArrayList<String[]>(); 523d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 533d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 543d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang // This is a watchdog thread which dumps stacks of other threads periodically. 553d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang private static Watchdog sWatchdog = new Watchdog(); 563d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 573d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang private static class Watchdog { 583d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang private ArrayList<WatchEntry> mList = new ArrayList<WatchEntry>(); 593d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang private HandlerThread mHandlerThread; 603d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang private Handler mHandler; 613d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang private Runnable mProcessRunnable = new Runnable() { 623d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang public void run() { 633d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang synchronized (Watchdog.this) { 643d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang processList(); 653d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 663d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 673d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang }; 683d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang private Random mRandom = new Random(); 693d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang private ProfileData mProfileData = new ProfileData(); 703d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 713d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang public Watchdog() { 723d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang mHandlerThread = new HandlerThread("Watchdog Handler", 733d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang Process.THREAD_PRIORITY_FOREGROUND); 743d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang mHandlerThread.start(); 753d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang mHandler = new Handler(mHandlerThread.getLooper()); 763d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 773d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 783d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang public synchronized void addWatchEntry(Thread thread, int cycleTime) { 793d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang WatchEntry e = new WatchEntry(); 803d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang e.thread = thread; 813d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang e.cycleTime = cycleTime; 823d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang int firstDelay = 1 + mRandom.nextInt(cycleTime); 833d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang e.wakeTime = (int) (System.nanoTime() / NS_PER_MS) + firstDelay; 843d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang mList.add(e); 853d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang processList(); 863d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 873d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 883d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang public synchronized void removeWatchEntry(Thread thread) { 893d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang for (int i = 0; i < mList.size(); i++) { 903d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang if (mList.get(i).thread == thread) { 913d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang mList.remove(i); 923d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang break; 933d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 943d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 953d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang processList(); 963d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 973d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 983d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang public synchronized void removeAllWatchEntries() { 993d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang mList.clear(); 1003d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang processList(); 1013d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 1023d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 1033d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang private void processList() { 1043d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang mHandler.removeCallbacks(mProcessRunnable); 1053d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang if (mList.size() == 0) return; 1063d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 1073d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang int currentTime = (int) (System.nanoTime() / NS_PER_MS); 1083d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang int nextWakeTime = 0; 1093d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 1103d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang for (WatchEntry entry : mList) { 1113d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang if (currentTime > entry.wakeTime) { 1123d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang entry.wakeTime += entry.cycleTime; 1133d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang Thread thread = entry.thread; 1143d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang sampleStack(entry); 1153d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 1163d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 1173d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang if (entry.wakeTime > nextWakeTime) { 1183d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang nextWakeTime = entry.wakeTime; 1193d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 1203d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 1213d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 1223d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang long delay = nextWakeTime - currentTime; 1233d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang mHandler.postDelayed(mProcessRunnable, delay); 1243d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 1253d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 1263d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang private void sampleStack(WatchEntry entry) { 1273d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang Thread thread = entry.thread; 1283d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang StackTraceElement[] stack = thread.getStackTrace(); 1293d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang String[] lines = new String[stack.length]; 1303d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang for (int i = 0; i < stack.length; i++) { 1313d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang lines[i] = stack[i].toString(); 1323d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 1333d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang if (entry.isHolding) { 1343d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang entry.holdingStacks.add(lines); 1353d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } else { 1363d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang mProfileData.addSample(lines); 1373d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 1383d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 1393d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 1403d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang private WatchEntry findEntry(Thread thread) { 1413d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang for (int i = 0; i < mList.size(); i++) { 1423d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang WatchEntry entry = mList.get(i); 1433d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang if (entry.thread == thread) return entry; 1443d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 1453d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang return null; 1463d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 1473d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 1483d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang public synchronized void dumpToFile(String filename) { 1493d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang mProfileData.dumpToFile(filename); 1503d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 1513d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 1523d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang public synchronized void reset() { 1533d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang mProfileData.reset(); 1543d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 1553d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 1563d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang public synchronized void hold(Thread t) { 1573d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang WatchEntry entry = findEntry(t); 1583d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 1593d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang // This can happen if the profiling is disabled (probably from 1603d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang // another thread). Same check is applied in commit() and drop() 1613d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang // below. 1623d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang if (entry == null) return; 1633d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 1643d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang entry.isHolding = true; 1653d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 1663d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 1673d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang public synchronized void commit(Thread t) { 1683d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang WatchEntry entry = findEntry(t); 1693d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang if (entry == null) return; 1703d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang ArrayList<String[]> stacks = entry.holdingStacks; 1713d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang for (int i = 0; i < stacks.size(); i++) { 1723d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang mProfileData.addSample(stacks.get(i)); 1733d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 1743d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang entry.isHolding = false; 1753d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang entry.holdingStacks.clear(); 1763d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 1773d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 1783d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang public synchronized void drop(Thread t) { 1793d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang WatchEntry entry = findEntry(t); 1803d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang if (entry == null) return; 1813d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang entry.isHolding = false; 1823d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang entry.holdingStacks.clear(); 1833d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 1843d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 1853d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 1863d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang // Enable profiling for the calling thread. Periodically (every cycleTimeInMs 1873d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang // milliseconds) sample the stack trace of the calling thread. 1883d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang public static void enable(int cycleTimeInMs) { 1893d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang Thread t = Thread.currentThread(); 1903d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang sWatchdog.addWatchEntry(t, cycleTimeInMs); 1913d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 1923d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 1933d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang // Disable profiling for the calling thread. 1943d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang public static void disable() { 1953d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang sWatchdog.removeWatchEntry(Thread.currentThread()); 1963d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 1973d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 1983d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang // Disable profiling for all threads. 1993d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang public static void disableAll() { 2003d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang sWatchdog.removeAllWatchEntries(); 2013d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 2023d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 2033d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang // Dump the profiling data to a file. 2043d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang public static void dumpToFile(String filename) { 2053d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang sWatchdog.dumpToFile(filename); 2063d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 2073d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 2083d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang // Reset the collected profiling data. 2093d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang public static void reset() { 2103d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang sWatchdog.reset(); 2113d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 2123d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 2133d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang // Hold the future samples coming from current thread until commit() or 2143d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang // drop() is called, and those samples are recorded or ignored as a result. 2153d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang // This must called after enable() to be effective. 2163d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang public static void hold() { 2173d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang sWatchdog.hold(Thread.currentThread()); 2183d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 2193d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 2203d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang public static void commit() { 2213d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang sWatchdog.commit(Thread.currentThread()); 2223d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 2233d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 2243d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang public static void drop() { 2253d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang sWatchdog.drop(Thread.currentThread()); 2263d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 2273d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang} 228