Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(552)

Side by Side Diff: base/android/java/src/org/chromium/base/SystemMessageHandler.java

Issue 575103002: [Android] Experimental sync barrier detection for tracing (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.base; 5 package org.chromium.base;
6 6
7 import android.os.Handler; 7 import android.os.Handler;
8 import android.os.Message; 8 import android.os.Message;
9 import android.os.MessageQueue;
10 import android.util.Log;
11
12 import java.lang.reflect.Field;
13 import java.lang.reflect.InvocationTargetException;
14 import java.lang.reflect.Method;
9 15
10 class SystemMessageHandler extends Handler { 16 class SystemMessageHandler extends Handler {
11 17
18 private static final String TAG = "SystemMessageHandler";
19
12 private static final int SCHEDULED_WORK = 1; 20 private static final int SCHEDULED_WORK = 1;
13 private static final int DELAYED_SCHEDULED_WORK = 2; 21 private static final int DELAYED_SCHEDULED_WORK = 2;
14 22
15 // Native class pointer set by the constructor of the SharedClient native cl ass. 23 // Native class pointer set by the constructor of the SharedClient native cl ass.
16 private long mMessagePumpDelegateNative = 0; 24 private long mMessagePumpDelegateNative = 0;
17 private long mDelayedScheduledTimeTicks = 0; 25 private long mDelayedScheduledTimeTicks = 0;
18 26
27 private MessageQueue mMessageQueue;
28 private Field mMessageQueueMessageField;
29 private Field mMessageTargetField;
30
31 private final long mSyncBarrierTraceId;
32 private boolean mQueueHasBarrier;
33
19 private SystemMessageHandler(long messagePumpDelegateNative) { 34 private SystemMessageHandler(long messagePumpDelegateNative) {
20 mMessagePumpDelegateNative = messagePumpDelegateNative; 35 mMessagePumpDelegateNative = messagePumpDelegateNative;
21 } 36 mSyncBarrierTraceId = hashCode();
37 tryEnableSyncBarrierDetection();
38 }
22 39
23 @Override 40 @Override
24 public void handleMessage(Message msg) { 41 public void handleMessage(Message msg) {
42 updateWhetherQueueHasBlockingSyncBarrier();
25 if (msg.what == DELAYED_SCHEDULED_WORK) { 43 if (msg.what == DELAYED_SCHEDULED_WORK) {
26 mDelayedScheduledTimeTicks = 0; 44 mDelayedScheduledTimeTicks = 0;
27 } 45 }
28 nativeDoRunLoopOnce(mMessagePumpDelegateNative, mDelayedScheduledTimeTic ks); 46 nativeDoRunLoopOnce(mMessagePumpDelegateNative, mDelayedScheduledTimeTic ks);
29 } 47 }
30 48
31 @SuppressWarnings("unused") 49 @SuppressWarnings("unused")
32 @CalledByNative 50 @CalledByNative
33 private void scheduleWork() { 51 private void scheduleWork() {
52 updateWhetherQueueHasBlockingSyncBarrier();
53 if (mQueueHasBarrier) TraceEvent.instant("SystemMessageHandler:immediate WorkBlocked");
34 sendEmptyMessage(SCHEDULED_WORK); 54 sendEmptyMessage(SCHEDULED_WORK);
35 } 55 }
36 56
37 @SuppressWarnings("unused") 57 @SuppressWarnings("unused")
38 @CalledByNative 58 @CalledByNative
39 private void scheduleDelayedWork(long delayedTimeTicks, long millis) { 59 private void scheduleDelayedWork(long delayedTimeTicks, long millis) {
40 if (mDelayedScheduledTimeTicks != 0) { 60 if (mDelayedScheduledTimeTicks != 0) {
41 removeMessages(DELAYED_SCHEDULED_WORK); 61 removeMessages(DELAYED_SCHEDULED_WORK);
42 } 62 }
43 mDelayedScheduledTimeTicks = delayedTimeTicks; 63 mDelayedScheduledTimeTicks = delayedTimeTicks;
64 updateWhetherQueueHasBlockingSyncBarrier();
65 if (mQueueHasBarrier) TraceEvent.instant("SystemMessageHandler:delayedWo rkBlocked");
44 sendEmptyMessageDelayed(DELAYED_SCHEDULED_WORK, millis); 66 sendEmptyMessageDelayed(DELAYED_SCHEDULED_WORK, millis);
45 } 67 }
46 68
47 @SuppressWarnings("unused") 69 @SuppressWarnings("unused")
48 @CalledByNative 70 @CalledByNative
49 private void removeAllPendingMessages() { 71 private void removeAllPendingMessages() {
72 updateWhetherQueueHasBlockingSyncBarrier();
50 removeMessages(SCHEDULED_WORK); 73 removeMessages(SCHEDULED_WORK);
51 removeMessages(DELAYED_SCHEDULED_WORK); 74 removeMessages(DELAYED_SCHEDULED_WORK);
52 } 75 }
53 76
77 private void updateWhetherQueueHasBlockingSyncBarrier() {
epennerAtGoogle 2014/09/22 21:26:48 If there is any cost to analyzing a message, we co
jdduke (slow) 2014/09/22 21:32:57 Ohh, I like that, didn't realize that was exposed
78 if (mMessageQueue == null) return;
79 final Message queueHead = (Message)getField(mMessageQueue, mMessageQueue MessageField);
80 final boolean queueHasBarrier = isBarrierMessage(queueHead);
81 setQueueHasBarrier(queueHasBarrier);
82 }
83
84 private boolean isBarrierMessage(Message message) {
85 if (message == null) return false;
86 // Sync barrier messages have null targets.
87 return getField(message, mMessageTargetField) == null;
88 }
89
90 private void tryEnableSyncBarrierDetection() {
91 boolean success = false;
92 try {
93 Class<?> looperClass = Class.forName("android.os.Looper");
94 Method getQueueMethod = looperClass.getMethod("getQueue", new Class[ ]{});
95 mMessageQueue = (MessageQueue)(getQueueMethod.invoke(getLooper()));
96
97 mMessageQueueMessageField = mMessageQueue.getClass().getDeclaredFiel d("mMessages");
98 mMessageQueueMessageField.setAccessible(true);
99
100 mMessageTargetField = new Message().getClass().getDeclaredField("tar get");
101 mMessageTargetField.setAccessible(true);
102
103 success = true;
104 } catch (ClassNotFoundException e) {
105 Log.e(TAG, "Failed to find class: " + e);
106 } catch (NoSuchMethodException e) {
107 Log.e(TAG, "Failed to load method: " + e);
108 } catch (NoSuchFieldException e) {
109 Log.e(TAG, "Failed to load field: " + e);
110 } catch (InvocationTargetException e) {
111 Log.e(TAG, "Failed invocation: " + e);
112 } catch (IllegalAccessException e) {
113 Log.e(TAG, "Illegal access to reflected invocation: " + e);
114 } catch (RuntimeException e) {
115 Log.e(TAG, e.toString());
116 } finally {
117 if (!success) disableSyncBarrierDetection();
118 }
119 }
120
121 private void disableSyncBarrierDetection() {
122 Log.e(TAG, "Unexpected error with sync barrier detection, disabling.");
123 mMessageQueue = null;
124 mMessageQueueMessageField = null;
125 mMessageTargetField = null;
126 setQueueHasBarrier(false);
127 }
128
129 private void setQueueHasBarrier(boolean queueHasBarrier) {
130 if (queueHasBarrier == mQueueHasBarrier) return;
131 mQueueHasBarrier = queueHasBarrier;
132 if (mQueueHasBarrier) {
133 TraceEvent.startAsync("SyncBarrier", mSyncBarrierTraceId);
134 } else {
135 TraceEvent.finishAsync("SyncBarrier", mSyncBarrierTraceId);
136 }
137 }
138
139 private Object getField(Object object, Field field) {
140 try {
141 return field.get(object);
142 } catch (IllegalAccessException e) {
143 Log.e(TAG, "Failed field access: " + e);
144 disableSyncBarrierDetection();
145 }
146 return null;
147 }
148
54 @CalledByNative 149 @CalledByNative
55 private static SystemMessageHandler create(long messagePumpDelegateNative) { 150 private static SystemMessageHandler create(long messagePumpDelegateNative) {
56 return new SystemMessageHandler(messagePumpDelegateNative); 151 return new SystemMessageHandler(messagePumpDelegateNative);
57 } 152 }
58 153
59 private native void nativeDoRunLoopOnce( 154 private native void nativeDoRunLoopOnce(
60 long messagePumpDelegateNative, long delayedScheduledTimeTicks); 155 long messagePumpDelegateNative, long delayedScheduledTimeTicks);
61 } 156 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698