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

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: Code review 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.Looper;
8 import android.os.Message; 9 import android.os.Message;
10 import android.os.MessageQueue;
11 import android.util.Log;
12
13 import java.lang.reflect.Field;
14 import java.lang.reflect.InvocationTargetException;
15 import java.lang.reflect.Method;
9 16
10 class SystemMessageHandler extends Handler { 17 class SystemMessageHandler extends Handler {
11 18
19 private static final String TAG = "SystemMessageHandler";
20
12 private static final int SCHEDULED_WORK = 1; 21 private static final int SCHEDULED_WORK = 1;
13 private static final int DELAYED_SCHEDULED_WORK = 2; 22 private static final int DELAYED_SCHEDULED_WORK = 2;
14 23
15 // Native class pointer set by the constructor of the SharedClient native cl ass. 24 // Native class pointer set by the constructor of the SharedClient native cl ass.
16 private long mMessagePumpDelegateNative = 0; 25 private long mMessagePumpDelegateNative = 0;
17 private long mDelayedScheduledTimeTicks = 0; 26 private long mDelayedScheduledTimeTicks = 0;
18 27
28 // The following members are used to detect and trace the presence of sync
29 // barriers in Android's MessageQueue. Note that this detection is
30 // experimental, temporary and intended only for diagnostic purposes.
31 private MessageQueue mMessageQueue;
32 private Field mMessageQueueMessageField;
33 private Field mMessageTargetField;
34 private boolean mQueueHasSyncBarrier;
35 private long mSyncBarrierTraceId;
36
19 private SystemMessageHandler(long messagePumpDelegateNative) { 37 private SystemMessageHandler(long messagePumpDelegateNative) {
20 mMessagePumpDelegateNative = messagePumpDelegateNative; 38 mMessagePumpDelegateNative = messagePumpDelegateNative;
21 } 39 tryEnableSyncBarrierDetection();
40 }
22 41
23 @Override 42 @Override
24 public void handleMessage(Message msg) { 43 public void handleMessage(Message msg) {
44 updateWhetherQueueHasBlockingSyncBarrier();
25 if (msg.what == DELAYED_SCHEDULED_WORK) { 45 if (msg.what == DELAYED_SCHEDULED_WORK) {
26 mDelayedScheduledTimeTicks = 0; 46 mDelayedScheduledTimeTicks = 0;
27 } 47 }
28 nativeDoRunLoopOnce(mMessagePumpDelegateNative, mDelayedScheduledTimeTic ks); 48 nativeDoRunLoopOnce(mMessagePumpDelegateNative, mDelayedScheduledTimeTic ks);
29 } 49 }
30 50
31 @SuppressWarnings("unused") 51 @SuppressWarnings("unused")
32 @CalledByNative 52 @CalledByNative
33 private void scheduleWork() { 53 private void scheduleWork() {
54 updateWhetherQueueHasBlockingSyncBarrier();
55 if (mQueueHasSyncBarrier) TraceEvent.instant("SystemMessageHandler:immed iateWorkBlocked");
34 sendEmptyMessage(SCHEDULED_WORK); 56 sendEmptyMessage(SCHEDULED_WORK);
35 } 57 }
36 58
37 @SuppressWarnings("unused") 59 @SuppressWarnings("unused")
38 @CalledByNative 60 @CalledByNative
39 private void scheduleDelayedWork(long delayedTimeTicks, long millis) { 61 private void scheduleDelayedWork(long delayedTimeTicks, long millis) {
40 if (mDelayedScheduledTimeTicks != 0) { 62 if (mDelayedScheduledTimeTicks != 0) {
41 removeMessages(DELAYED_SCHEDULED_WORK); 63 removeMessages(DELAYED_SCHEDULED_WORK);
42 } 64 }
43 mDelayedScheduledTimeTicks = delayedTimeTicks; 65 mDelayedScheduledTimeTicks = delayedTimeTicks;
66 updateWhetherQueueHasBlockingSyncBarrier();
67 if (mQueueHasSyncBarrier) TraceEvent.instant("SystemMessageHandler:delay edWorkBlocked");
44 sendEmptyMessageDelayed(DELAYED_SCHEDULED_WORK, millis); 68 sendEmptyMessageDelayed(DELAYED_SCHEDULED_WORK, millis);
45 } 69 }
46 70
47 @SuppressWarnings("unused") 71 @SuppressWarnings("unused")
48 @CalledByNative 72 @CalledByNative
49 private void removeAllPendingMessages() { 73 private void removeAllPendingMessages() {
74 updateWhetherQueueHasBlockingSyncBarrier();
50 removeMessages(SCHEDULED_WORK); 75 removeMessages(SCHEDULED_WORK);
51 removeMessages(DELAYED_SCHEDULED_WORK); 76 removeMessages(DELAYED_SCHEDULED_WORK);
52 } 77 }
53 78
79 private void updateWhetherQueueHasBlockingSyncBarrier() {
80 if (mMessageQueue == null) return;
81 // As barrier detection is only used for tracing, early out when tracing
82 // is disabled to avoid any potential performance penalties.
83 if (!TraceEvent.enabled()) {
84 mQueueHasSyncBarrier = false;
85 return;
86 }
87 Message queueHead = (Message)getField(mMessageQueue, mMessageQueueMessag eField);
88 setqueueHasSyncBarrier(isSyncBarrierMessage(queueHead));
89 }
90
91 private boolean isSyncBarrierMessage(Message message) {
92 if (message == null) return false;
93 // Sync barrier messages have null targets.
94 return getField(message, mMessageTargetField) == null;
95 }
96
97 private void tryEnableSyncBarrierDetection() {
98 assert mMessageQueue == null;
99
100 boolean success = false;
101 try {
102 Method getQueueMethod = Looper.class.getMethod("getQueue", new Class []{});
103 mMessageQueue = (MessageQueue)getQueueMethod.invoke(getLooper());
104
105 mMessageQueueMessageField = mMessageQueue.getClass().getDeclaredFiel d("mMessages");
106 mMessageQueueMessageField.setAccessible(true);
107
108 mMessageTargetField = Message.class.getDeclaredField("target");
109 mMessageTargetField.setAccessible(true);
110
111 mSyncBarrierTraceId = hashCode();
112
113 success = true;
114 } catch (NoSuchMethodException e) {
115 Log.e(TAG, "Failed to load method: " + e);
116 } catch (NoSuchFieldException e) {
117 Log.e(TAG, "Failed to load field: " + e);
118 } catch (InvocationTargetException e) {
119 Log.e(TAG, "Failed invocation: " + e);
120 } catch (IllegalAccessException e) {
121 Log.e(TAG, "Illegal access to reflected invocation: " + e);
122 } catch (IllegalArgumentException e) {
123 Log.e(TAG, "Illegal argument to reflected invocation: " + e);
124 } catch (RuntimeException e) {
125 Log.e(TAG, e.toString());
126 } finally {
127 if (!success) disableSyncBarrierDetection();
128 }
129 }
130
131 private void disableSyncBarrierDetection() {
132 Log.e(TAG, "Unexpected error with sync barrier detection, disabling.");
133 mMessageQueue = null;
134 mMessageQueueMessageField = null;
135 mMessageTargetField = null;
136 setqueueHasSyncBarrier(false);
137 }
138
139 private void setqueueHasSyncBarrier(boolean queueHasSyncBarrier) {
140 if (queueHasSyncBarrier == mQueueHasSyncBarrier) return;
141 mQueueHasSyncBarrier = queueHasSyncBarrier;
142 if (mQueueHasSyncBarrier) {
143 TraceEvent.startAsync("SyncBarrier", mSyncBarrierTraceId);
144 } else {
145 TraceEvent.finishAsync("SyncBarrier", mSyncBarrierTraceId);
146 }
147 }
148
149 private Object getField(Object object, Field field) {
150 try {
151 return field.get(object);
152 } catch (IllegalAccessException e) {
153 Log.e(TAG, "Failed field access: " + e);
154 disableSyncBarrierDetection();
155 }
156 return null;
157 }
158
54 @CalledByNative 159 @CalledByNative
55 private static SystemMessageHandler create(long messagePumpDelegateNative) { 160 private static SystemMessageHandler create(long messagePumpDelegateNative) {
56 return new SystemMessageHandler(messagePumpDelegateNative); 161 return new SystemMessageHandler(messagePumpDelegateNative);
57 } 162 }
58 163
59 private native void nativeDoRunLoopOnce( 164 private native void nativeDoRunLoopOnce(
60 long messagePumpDelegateNative, long delayedScheduledTimeTicks); 165 long messagePumpDelegateNative, long delayedScheduledTimeTicks);
61 } 166 }
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