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 android.os.Handler; 203d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Changimport android.os.HandlerThread; 213d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Changimport android.os.Process; 223d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 233d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Changimport java.util.ArrayList; 243d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Changimport java.util.Random; 253d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 263d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang// The Profile class is used to collect profiling information for a thread. It 273d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang// samples stack traces for a thread periodically. enable() and disable() is 283d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang// used to enable and disable profiling for the calling thread. The profiling 293d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang// information can then be dumped to a file using the dumpToFile() method. 303d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang// 313d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang// The disableAll() method can be used to disable profiling for all threads and 323d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang// can be called in onPause() to ensure all profiling is disabled when an 333d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang// activity is paused. 343d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Changpublic class Profile { 357817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @SuppressWarnings("unused") 363d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang private static final String TAG = "Profile"; 373d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang private static final int NS_PER_MS = 1000000; 383d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 393d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang // This is a watchdog entry for one thread. 403d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang // For every cycleTime period, we dump the stack of the thread. 413d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang private static class WatchEntry { 423d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang Thread thread; 433d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 443d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang // Both are in milliseconds 453d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang int cycleTime; 463d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang int wakeTime; 473d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 483d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang boolean isHolding; 493d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang ArrayList<String[]> holdingStacks = new ArrayList<String[]>(); 503d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 513d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 523d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang // This is a watchdog thread which dumps stacks of other threads periodically. 533d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang private static Watchdog sWatchdog = new Watchdog(); 543d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 553d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang private static class Watchdog { 563d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang private ArrayList<WatchEntry> mList = new ArrayList<WatchEntry>(); 573d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang private HandlerThread mHandlerThread; 583d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang private Handler mHandler; 593d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang private Runnable mProcessRunnable = new Runnable() { 607817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 613d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang public void run() { 623d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang synchronized (Watchdog.this) { 633d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang processList(); 643d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 653d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 663d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang }; 673d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang private Random mRandom = new Random(); 683d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang private ProfileData mProfileData = new ProfileData(); 693d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 703d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang public Watchdog() { 713d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang mHandlerThread = new HandlerThread("Watchdog Handler", 723d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang Process.THREAD_PRIORITY_FOREGROUND); 733d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang mHandlerThread.start(); 743d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang mHandler = new Handler(mHandlerThread.getLooper()); 753d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 763d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 773d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang public synchronized void addWatchEntry(Thread thread, int cycleTime) { 783d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang WatchEntry e = new WatchEntry(); 793d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang e.thread = thread; 803d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang e.cycleTime = cycleTime; 813d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang int firstDelay = 1 + mRandom.nextInt(cycleTime); 823d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang e.wakeTime = (int) (System.nanoTime() / NS_PER_MS) + firstDelay; 833d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang mList.add(e); 843d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang processList(); 853d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 863d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 873d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang public synchronized void removeWatchEntry(Thread thread) { 883d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang for (int i = 0; i < mList.size(); i++) { 893d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang if (mList.get(i).thread == thread) { 903d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang mList.remove(i); 913d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang break; 923d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 933d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 943d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang processList(); 953d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 963d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 973d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang public synchronized void removeAllWatchEntries() { 983d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang mList.clear(); 993d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang processList(); 1003d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 1013d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 1023d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang private void processList() { 1033d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang mHandler.removeCallbacks(mProcessRunnable); 1043d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang if (mList.size() == 0) return; 1053d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 1063d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang int currentTime = (int) (System.nanoTime() / NS_PER_MS); 1073d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang int nextWakeTime = 0; 1083d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 1093d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang for (WatchEntry entry : mList) { 1103d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang if (currentTime > entry.wakeTime) { 1113d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang entry.wakeTime += entry.cycleTime; 1123d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang Thread thread = entry.thread; 1133d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang sampleStack(entry); 1143d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 1153d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 1163d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang if (entry.wakeTime > nextWakeTime) { 1173d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang nextWakeTime = entry.wakeTime; 1183d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 1193d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 1203d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 1213d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang long delay = nextWakeTime - currentTime; 1223d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang mHandler.postDelayed(mProcessRunnable, delay); 1233d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 1243d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 1253d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang private void sampleStack(WatchEntry entry) { 1263d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang Thread thread = entry.thread; 1273d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang StackTraceElement[] stack = thread.getStackTrace(); 1283d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang String[] lines = new String[stack.length]; 1293d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang for (int i = 0; i < stack.length; i++) { 1303d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang lines[i] = stack[i].toString(); 1313d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 1323d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang if (entry.isHolding) { 1333d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang entry.holdingStacks.add(lines); 1343d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } else { 1353d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang mProfileData.addSample(lines); 1363d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 1373d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 1383d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 1393d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang private WatchEntry findEntry(Thread thread) { 1403d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang for (int i = 0; i < mList.size(); i++) { 1413d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang WatchEntry entry = mList.get(i); 1423d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang if (entry.thread == thread) return entry; 1433d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 1443d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang return null; 1453d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 1463d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 1473d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang public synchronized void dumpToFile(String filename) { 1483d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang mProfileData.dumpToFile(filename); 1493d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 1503d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 1513d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang public synchronized void reset() { 1523d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang mProfileData.reset(); 1533d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 1543d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 1553d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang public synchronized void hold(Thread t) { 1563d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang WatchEntry entry = findEntry(t); 1573d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 1583d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang // This can happen if the profiling is disabled (probably from 1593d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang // another thread). Same check is applied in commit() and drop() 1603d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang // below. 1613d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang if (entry == null) return; 1623d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 1633d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang entry.isHolding = true; 1643d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 1653d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 1663d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang public synchronized void commit(Thread t) { 1673d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang WatchEntry entry = findEntry(t); 1683d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang if (entry == null) return; 1693d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang ArrayList<String[]> stacks = entry.holdingStacks; 1703d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang for (int i = 0; i < stacks.size(); i++) { 1713d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang mProfileData.addSample(stacks.get(i)); 1723d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 1733d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang entry.isHolding = false; 1743d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang entry.holdingStacks.clear(); 1753d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 1763d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 1773d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang public synchronized void drop(Thread t) { 1783d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang WatchEntry entry = findEntry(t); 1793d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang if (entry == null) return; 1803d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang entry.isHolding = false; 1813d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang entry.holdingStacks.clear(); 1823d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 1833d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 1843d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 1853d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang // Enable profiling for the calling thread. Periodically (every cycleTimeInMs 1863d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang // milliseconds) sample the stack trace of the calling thread. 1873d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang public static void enable(int cycleTimeInMs) { 1883d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang Thread t = Thread.currentThread(); 1893d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang sWatchdog.addWatchEntry(t, cycleTimeInMs); 1903d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 1913d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 1923d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang // Disable profiling for the calling thread. 1933d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang public static void disable() { 1943d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang sWatchdog.removeWatchEntry(Thread.currentThread()); 1953d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 1963d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 1973d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang // Disable profiling for all threads. 1983d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang public static void disableAll() { 1993d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang sWatchdog.removeAllWatchEntries(); 2003d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 2013d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 2023d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang // Dump the profiling data to a file. 2033d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang public static void dumpToFile(String filename) { 2043d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang sWatchdog.dumpToFile(filename); 2053d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 2063d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 2073d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang // Reset the collected profiling data. 2083d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang public static void reset() { 2093d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang sWatchdog.reset(); 2103d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 2113d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 2123d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang // Hold the future samples coming from current thread until commit() or 2133d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang // drop() is called, and those samples are recorded or ignored as a result. 2143d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang // This must called after enable() to be effective. 2153d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang public static void hold() { 2163d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang sWatchdog.hold(Thread.currentThread()); 2173d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 2183d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 2193d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang public static void commit() { 2203d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang sWatchdog.commit(Thread.currentThread()); 2213d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 2223d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 2233d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang public static void drop() { 2243d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang sWatchdog.drop(Thread.currentThread()); 2253d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 2263d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang} 227