Loading core/java/android/os/Looper.java +8 −6 Original line number Diff line number Diff line Loading @@ -130,19 +130,20 @@ public class Looper { if (logging != null) { logging.println(">>>>> Dispatching to " + msg.target + " " + msg.callback + ": " + msg.what); wallStart = System.currentTimeMillis(); threadStart = SystemClock.currentThreadTimeMillis(); wallStart = SystemClock.currentTimeMicro(); threadStart = SystemClock.currentThreadTimeMicro(); } msg.target.dispatchMessage(msg); if (logging != null) { long wallTime = System.currentTimeMillis() - wallStart; long threadTime = SystemClock.currentThreadTimeMillis() - threadStart; long wallTime = SystemClock.currentTimeMicro() - wallStart; long threadTime = SystemClock.currentThreadTimeMicro() - threadStart; logging.println("<<<<< Finished to " + msg.target + " " + msg.callback); if (logging instanceof Profiler) { ((Profiler) logging).profile(msg, wallStart, wallTime, threadTime); ((Profiler) logging).profile(msg, wallStart, wallTime, threadStart, threadTime); } } Loading Loading @@ -247,6 +248,7 @@ public class Looper { * @hide */ public static interface Profiler { void profile(Message message, long wallStart, long wallTime, long threadTime); void profile(Message message, long wallStart, long wallTime, long threadStart, long threadTime); } } core/java/android/os/SystemClock.java +18 −0 Original line number Diff line number Diff line Loading @@ -157,4 +157,22 @@ public final class SystemClock { * @return elapsed milliseconds in the thread */ public static native long currentThreadTimeMillis(); /** * Returns microseconds running in the current thread. * * @return elapsed microseconds in the thread * * @hide */ public static native long currentThreadTimeMicro(); /** * Returns current wall time in microseconds. * * @return elapsed microseconds in wall time * * @hide */ public static native long currentTimeMicro(); } core/java/android/view/ViewDebug.java +42 −8 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.os.Environment; import android.os.Looper; import android.os.Message; import android.os.RemoteException; import android.os.SystemClock; import android.util.DisplayMetrics; import android.util.Log; import android.util.Printer; Loading Loading @@ -53,6 +54,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; Loading Loading @@ -455,11 +457,19 @@ public class ViewDebug { private static final String LOG_TAG = "LooperProfiler"; private final long mTraceWallStart; private final long mTraceThreadStart; private final ArrayList<Entry> mTraces = new ArrayList<Entry>(512); private final File mTraceFile; public LooperProfiler(File traceFile) { private final HashMap<String, Short> mTraceNames = new HashMap<String, Short>(32); private short mTraceId = 0; LooperProfiler(File traceFile) { mTraceFile = traceFile; mTraceWallStart = SystemClock.currentTimeMicro(); mTraceThreadStart = SystemClock.currentThreadTimeMicro(); } @Override Loading @@ -468,17 +478,28 @@ public class ViewDebug { } @Override public void profile(Message message, long wallStart, long wallTime, long threadTime) { public void profile(Message message, long wallStart, long wallTime, long threadStart, long threadTime) { Entry entry = new Entry(); entry.messageId = message.what; entry.name = message.getTarget().getMessageName(message); entry.traceId = getTraceId(message); entry.wallStart = wallStart; entry.wallTime = wallTime; entry.threadStart = threadStart; entry.threadTime = threadTime; mTraces.add(entry); } private short getTraceId(Message message) { String name = message.getTarget().getMessageName(message); Short traceId = mTraceNames.get(name); if (traceId == null) { traceId = mTraceId++; mTraceNames.put(name, traceId); } return traceId; } void save() { // Don't block the UI thread new Thread(new Runnable() { Loading @@ -502,6 +523,14 @@ public class ViewDebug { try { out.writeInt(LOOPER_PROFILER_VERSION); out.writeLong(mTraceWallStart); out.writeLong(mTraceThreadStart); out.writeInt(mTraceNames.size()); for (Map.Entry<String, Short> entry : mTraceNames.entrySet()) { saveTraceName(entry.getKey(), entry.getValue(), out); } out.writeInt(mTraces.size()); for (Entry entry : mTraces) { saveTrace(entry, out); Loading @@ -519,19 +548,24 @@ public class ViewDebug { } } private void saveTraceName(String name, short id, DataOutputStream out) throws IOException { out.writeShort(id); out.writeUTF(name); } private void saveTrace(Entry entry, DataOutputStream out) throws IOException { out.writeInt(entry.messageId); out.writeUTF(entry.name); out.writeShort(entry.traceId); out.writeLong(entry.wallStart); out.writeLong(entry.wallTime); out.writeLong(entry.threadStart); out.writeLong(entry.threadTime); } static class Entry { int messageId; String name; short traceId; long wallStart; long wallTime; long threadStart; long threadTime; } } Loading core/jni/android_os_SystemClock.cpp +36 −0 Original line number Diff line number Diff line Loading @@ -79,6 +79,38 @@ static jlong android_os_SystemClock_currentThreadTimeMillis(JNIEnv* env, #endif } /* * native public static long currentThreadTimeMicro(); */ static jlong android_os_SystemClock_currentThreadTimeMicro(JNIEnv* env, jobject clazz) { #if defined(HAVE_POSIX_CLOCKS) struct timespec tm; clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tm); return tm.tv_sec * 1000000LL + tm.tv_nsec / 1000; #else struct timeval tv; gettimeofday(&tv, NULL); return tv.tv_sec * 1000000LL + tv.tv_nsec / 1000; #endif } /* * native public static long currentTimeMicro(); */ static jlong android_os_SystemClock_currentTimeMicro(JNIEnv* env, jobject clazz) { struct timeval tv; gettimeofday(&tv, NULL); return tv.tv_sec * 1000000LL + tv.tv_usec; } /* * JNI registration. */ Loading @@ -92,6 +124,10 @@ static JNINativeMethod gMethods[] = { (void*) android_os_SystemClock_elapsedRealtime }, { "currentThreadTimeMillis", "()J", (void*) android_os_SystemClock_currentThreadTimeMillis }, { "currentThreadTimeMicro", "()J", (void*) android_os_SystemClock_currentThreadTimeMicro }, { "currentTimeMicro", "()J", (void*) android_os_SystemClock_currentTimeMicro }, }; int register_android_os_SystemClock(JNIEnv* env) { Loading Loading
core/java/android/os/Looper.java +8 −6 Original line number Diff line number Diff line Loading @@ -130,19 +130,20 @@ public class Looper { if (logging != null) { logging.println(">>>>> Dispatching to " + msg.target + " " + msg.callback + ": " + msg.what); wallStart = System.currentTimeMillis(); threadStart = SystemClock.currentThreadTimeMillis(); wallStart = SystemClock.currentTimeMicro(); threadStart = SystemClock.currentThreadTimeMicro(); } msg.target.dispatchMessage(msg); if (logging != null) { long wallTime = System.currentTimeMillis() - wallStart; long threadTime = SystemClock.currentThreadTimeMillis() - threadStart; long wallTime = SystemClock.currentTimeMicro() - wallStart; long threadTime = SystemClock.currentThreadTimeMicro() - threadStart; logging.println("<<<<< Finished to " + msg.target + " " + msg.callback); if (logging instanceof Profiler) { ((Profiler) logging).profile(msg, wallStart, wallTime, threadTime); ((Profiler) logging).profile(msg, wallStart, wallTime, threadStart, threadTime); } } Loading Loading @@ -247,6 +248,7 @@ public class Looper { * @hide */ public static interface Profiler { void profile(Message message, long wallStart, long wallTime, long threadTime); void profile(Message message, long wallStart, long wallTime, long threadStart, long threadTime); } }
core/java/android/os/SystemClock.java +18 −0 Original line number Diff line number Diff line Loading @@ -157,4 +157,22 @@ public final class SystemClock { * @return elapsed milliseconds in the thread */ public static native long currentThreadTimeMillis(); /** * Returns microseconds running in the current thread. * * @return elapsed microseconds in the thread * * @hide */ public static native long currentThreadTimeMicro(); /** * Returns current wall time in microseconds. * * @return elapsed microseconds in wall time * * @hide */ public static native long currentTimeMicro(); }
core/java/android/view/ViewDebug.java +42 −8 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.os.Environment; import android.os.Looper; import android.os.Message; import android.os.RemoteException; import android.os.SystemClock; import android.util.DisplayMetrics; import android.util.Log; import android.util.Printer; Loading Loading @@ -53,6 +54,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; Loading Loading @@ -455,11 +457,19 @@ public class ViewDebug { private static final String LOG_TAG = "LooperProfiler"; private final long mTraceWallStart; private final long mTraceThreadStart; private final ArrayList<Entry> mTraces = new ArrayList<Entry>(512); private final File mTraceFile; public LooperProfiler(File traceFile) { private final HashMap<String, Short> mTraceNames = new HashMap<String, Short>(32); private short mTraceId = 0; LooperProfiler(File traceFile) { mTraceFile = traceFile; mTraceWallStart = SystemClock.currentTimeMicro(); mTraceThreadStart = SystemClock.currentThreadTimeMicro(); } @Override Loading @@ -468,17 +478,28 @@ public class ViewDebug { } @Override public void profile(Message message, long wallStart, long wallTime, long threadTime) { public void profile(Message message, long wallStart, long wallTime, long threadStart, long threadTime) { Entry entry = new Entry(); entry.messageId = message.what; entry.name = message.getTarget().getMessageName(message); entry.traceId = getTraceId(message); entry.wallStart = wallStart; entry.wallTime = wallTime; entry.threadStart = threadStart; entry.threadTime = threadTime; mTraces.add(entry); } private short getTraceId(Message message) { String name = message.getTarget().getMessageName(message); Short traceId = mTraceNames.get(name); if (traceId == null) { traceId = mTraceId++; mTraceNames.put(name, traceId); } return traceId; } void save() { // Don't block the UI thread new Thread(new Runnable() { Loading @@ -502,6 +523,14 @@ public class ViewDebug { try { out.writeInt(LOOPER_PROFILER_VERSION); out.writeLong(mTraceWallStart); out.writeLong(mTraceThreadStart); out.writeInt(mTraceNames.size()); for (Map.Entry<String, Short> entry : mTraceNames.entrySet()) { saveTraceName(entry.getKey(), entry.getValue(), out); } out.writeInt(mTraces.size()); for (Entry entry : mTraces) { saveTrace(entry, out); Loading @@ -519,19 +548,24 @@ public class ViewDebug { } } private void saveTraceName(String name, short id, DataOutputStream out) throws IOException { out.writeShort(id); out.writeUTF(name); } private void saveTrace(Entry entry, DataOutputStream out) throws IOException { out.writeInt(entry.messageId); out.writeUTF(entry.name); out.writeShort(entry.traceId); out.writeLong(entry.wallStart); out.writeLong(entry.wallTime); out.writeLong(entry.threadStart); out.writeLong(entry.threadTime); } static class Entry { int messageId; String name; short traceId; long wallStart; long wallTime; long threadStart; long threadTime; } } Loading
core/jni/android_os_SystemClock.cpp +36 −0 Original line number Diff line number Diff line Loading @@ -79,6 +79,38 @@ static jlong android_os_SystemClock_currentThreadTimeMillis(JNIEnv* env, #endif } /* * native public static long currentThreadTimeMicro(); */ static jlong android_os_SystemClock_currentThreadTimeMicro(JNIEnv* env, jobject clazz) { #if defined(HAVE_POSIX_CLOCKS) struct timespec tm; clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tm); return tm.tv_sec * 1000000LL + tm.tv_nsec / 1000; #else struct timeval tv; gettimeofday(&tv, NULL); return tv.tv_sec * 1000000LL + tv.tv_nsec / 1000; #endif } /* * native public static long currentTimeMicro(); */ static jlong android_os_SystemClock_currentTimeMicro(JNIEnv* env, jobject clazz) { struct timeval tv; gettimeofday(&tv, NULL); return tv.tv_sec * 1000000LL + tv.tv_usec; } /* * JNI registration. */ Loading @@ -92,6 +124,10 @@ static JNINativeMethod gMethods[] = { (void*) android_os_SystemClock_elapsedRealtime }, { "currentThreadTimeMillis", "()J", (void*) android_os_SystemClock_currentThreadTimeMillis }, { "currentThreadTimeMicro", "()J", (void*) android_os_SystemClock_currentThreadTimeMicro }, { "currentTimeMicro", "()J", (void*) android_os_SystemClock_currentTimeMicro }, }; int register_android_os_SystemClock(JNIEnv* env) { Loading