Skip to content

Commit d401a53

Browse files
faddenAndroid (Google) Code Review
authored andcommitted
Merge "Improve systrace tag propagation" into jb-mr1-dev
2 parents a665df5 + d11ca4d commit d401a53

File tree

1 file changed

+50
-6
lines changed

1 file changed

+50
-6
lines changed

core/java/android/os/Trace.java

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package android.os;
1818

19+
import android.util.Log;
20+
1921
/**
2022
* Writes trace events to the kernel trace buffer. These trace events can be
2123
* collected using the "atrace" program for offline analysis.
@@ -27,6 +29,8 @@
2729
* @hide
2830
*/
2931
public final class Trace {
32+
private static final String TAG = "Trace";
33+
3034
// These tags must be kept in sync with frameworks/native/include/utils/Trace.h.
3135
public static final long TRACE_TAG_NEVER = 0;
3236
public static final long TRACE_TAG_ALWAYS = 1L << 0;
@@ -49,32 +53,72 @@ public final class Trace {
4953

5054
public static final String PROPERTY_TRACE_TAG_ENABLEFLAGS = "debug.atrace.tags.enableflags";
5155

52-
private static long sEnabledTags = nativeGetEnabledTags();
56+
// This works as a "not ready" flag because TRACE_TAG_ALWAYS is always set.
57+
private static final long TRACE_FLAGS_NOT_READY = 0;
58+
59+
// Must be volatile to avoid word tearing.
60+
private static volatile long sEnabledTags = TRACE_FLAGS_NOT_READY;
5361

5462
private static native long nativeGetEnabledTags();
5563
private static native void nativeTraceCounter(long tag, String name, int value);
5664
private static native void nativeTraceBegin(long tag, String name);
5765
private static native void nativeTraceEnd(long tag);
5866

5967
static {
68+
// We configure two separate change callbacks, one in Trace.cpp and one here. The
69+
// native callback reads the tags from the system property, and this callback
70+
// reads the value that the native code retrieved. It's essential that the native
71+
// callback executes first.
72+
//
73+
// The system provides ordering through a priority level. Callbacks made through
74+
// SystemProperties.addChangeCallback currently have a negative priority, while
75+
// our native code is using a priority of zero.
6076
SystemProperties.addChangeCallback(new Runnable() {
6177
@Override public void run() {
62-
sEnabledTags = nativeGetEnabledTags();
78+
cacheEnabledTags();
6379
}
6480
});
6581
}
6682

6783
private Trace() {
6884
}
6985

86+
/**
87+
* Caches a copy of the enabled-tag bits. The "master" copy is held by the native code,
88+
* and comes from the PROPERTY_TRACE_TAG_ENABLEFLAGS property.
89+
* <p>
90+
* If the native code hasn't yet read the property, we will cause it to do one-time
91+
* initialization. We don't want to do this during class init, because this class is
92+
* preloaded, so all apps would be stuck with whatever the zygote saw. (The zygote
93+
* doesn't see the system-property update broadcasts.)
94+
* <p>
95+
* We want to defer initialization until the first use by an app, post-zygote.
96+
* <p>
97+
* We're okay if multiple threads call here simultaneously -- the native state is
98+
* synchronized, and sEnabledTags is volatile (prevents word tearing).
99+
*/
100+
private static long cacheEnabledTags() {
101+
long tags = nativeGetEnabledTags();
102+
if (tags == TRACE_FLAGS_NOT_READY) {
103+
Log.w(TAG, "Unexpected value from nativeGetEnabledTags: " + tags);
104+
// keep going
105+
}
106+
sEnabledTags = tags;
107+
return tags;
108+
}
109+
70110
/**
71111
* Returns true if a trace tag is enabled.
72112
*
73113
* @param traceTag The trace tag to check.
74114
* @return True if the trace tag is valid.
75115
*/
76116
public static boolean isTagEnabled(long traceTag) {
77-
return (sEnabledTags & traceTag) != 0;
117+
long tags = sEnabledTags;
118+
if (tags == TRACE_FLAGS_NOT_READY) {
119+
tags = cacheEnabledTags();
120+
}
121+
return (tags & traceTag) != 0;
78122
}
79123

80124
/**
@@ -85,7 +129,7 @@ public static boolean isTagEnabled(long traceTag) {
85129
* @param counterValue The counter value.
86130
*/
87131
public static void traceCounter(long traceTag, String counterName, int counterValue) {
88-
if ((sEnabledTags & traceTag) != 0) {
132+
if (isTagEnabled(traceTag)) {
89133
nativeTraceCounter(traceTag, counterName, counterValue);
90134
}
91135
}
@@ -98,7 +142,7 @@ public static void traceCounter(long traceTag, String counterName, int counterVa
98142
* @param methodName The method name to appear in the trace.
99143
*/
100144
public static void traceBegin(long traceTag, String methodName) {
101-
if ((sEnabledTags & traceTag) != 0) {
145+
if (isTagEnabled(traceTag)) {
102146
nativeTraceBegin(traceTag, methodName);
103147
}
104148
}
@@ -110,7 +154,7 @@ public static void traceBegin(long traceTag, String methodName) {
110154
* @param traceTag The trace tag.
111155
*/
112156
public static void traceEnd(long traceTag) {
113-
if ((sEnabledTags & traceTag) != 0) {
157+
if (isTagEnabled(traceTag)) {
114158
nativeTraceEnd(traceTag);
115159
}
116160
}

0 commit comments

Comments
 (0)