背景:
常见使用perfetto进行看方法调用时候,每个方法执行都是有一个个片段,因为代码中加入atrace时候都有对应begin和end方法成对出现,哪怕ATRACE_CALL这种宏其实也是一个临时对象进行构造时候调用atrace_begin,在析构方法中atrace_end。

正因为都是有调用atrace的开始和结束方法才可以看到方法片段。
上面是我们的常用打印atrace方法情况,但是大家有没有想过我们打印日志其实是一个瞬时动作,直接调用一下ALOGE方法就可以这个时间点输出日志,完全不需要begin和end成对打印。
ALOGE(fmt, ##__VA_ARGS__); \
那么如何在perfetto中也实现类似日志瞬时打印ALOGE这种输出功能呢?
Perfetto中瞬时输出功能剖析
其实system/core/libcutils/include/cutils/trace.h
本身有这种瞬时输出的相关api,具体就是如下两个方法:
/**
* Trace an instantaneous context. name is used to identify the context.
*
* An "instant" is an event with no defined duration. Visually is displayed like a single marker
* in the timeline (rather than a span, in the case of begin/end events).
*
* By default, instant events are added into a dedicated track that has the same name of the event.
* Use atrace_instant_for_track to put different instant events into the same timeline track/row.
*/
#define ATRACE_INSTANT(name) atrace_instant(ATRACE_TAG, name)
static inline void atrace_instant(uint64_t tag, const char* name) {
if (CC_UNLIKELY(atrace_is_tag_enabled(tag))) {
atrace_instant_body(name);
}
}
/**
* Trace an instantaneous context. name is used to identify the context.
* track_name is the name of the row where the event should be recorded.
*
* An "instant" is an event with no defined duration. Visually is displayed like a single marker
* in the timeline (rather than a span, in the case of begin/end events).
*/
#define ATRACE_INSTANT_FOR_TRACK(trackName, name) \
atrace_instant_for_track(ATRACE_TAG, trackName, name)
static inline void atrace_instant_for_track(uint64_t tag, const char* track_name,
const char* name) {
if (CC_UNLIKELY(atrace_is_tag_enabled(tag))) {
atrace_instant_for_track_body(track_name, name);
}
}
注释也写的很明确,ATRACE_INSTANT这个宏就是代表一个瞬时的事件,没有持续时间片段概念,类似一个ALOGE打印一样输出某个瞬时时间点打印出。
还有另一个ATRACE_INSTANT_FOR_TRACK这个宏,功能也和ATRACE_INSTANT一样就是代表一个在Perfetto上的瞬时事件,但是这里多了一个trackName参数,这个trackName参数就是代表轨迹名字,怎么理解这个track呢?
其实如果定义专门traceName后,就是Perfetto会有单独一行来展示这些瞬时事件,他的作用最重要就是把多个地方的瞬时事件可以归纳到同一个trace即在Perfetto的同一行进行展示出来,就像log一样一样可以按时间排列进行上下展示一样,具体理解的话,下面会有代码和图片结合就简单多了。
ATRACE_INSTANT的典型调用和Perfetto展示
其实这个瞬时输出功能在aosp15版本的SurfaceFlinger中就有大量使用这种方式进行打印。
frameworks/native/services/surfaceflinger/Layer.cpp
这里调用是SFTRACE_FORMAT_INSTANT,看看这个宏:
frameworks/native/services/surfaceflinger/common/include/common/trace.h
#define SFTRACE_FORMAT_INSTANT(fmt, ...) \
::tracing_perfetto::traceFormatInstant(ATRACE_TAG, fmt, ##__VA_ARGS__)
frameworks/native/libs/tracing_perfetto/tracing_perfetto.cpp
void traceFormatInstant(uint64_t category, const char* fmt, ...) {
//省略
atrace_instant(category, buf);
//省略
}
可以看到最后就是调用到了atrace_instant。
atrace_instant在Perfetto的展现:
可以看到atrace_instant在Perfetto就是一个朝上的小箭头,这里大家可能和以前async的binder调用要区分一下:

ATRACE_INSTANT_FOR_TRACK的典型调用和Perfetto展示
ATRACE_INSTANT_FOR_TRACK本质就是和上面的ATRACE_INSTANT属于一个东西,只不过会把瞬时事件放入到固定的track中,这里给大家使用demo来实战展示一下:
在
frameworks/native/services/surfaceflinger/Layer.cpp
的两个方法都有加入ATRACE_INSTANT_FOR_TRACK调用


把setBuffer和latchBufferImpl两个方法都在traceName为TrackTestSf-1中进行展示。
Perfetto中效果如下:

更多framework实战开发干货,请关注下面“千里马学框架”
1126

被折叠的 条评论
为什么被折叠?



