mirror of
https://gitlab.freedesktop.org/wayland/weston.git
synced 2026-05-07 03:48:02 +02:00
libweston: Introduce Perfetto debug annotations
Introduce a bunch of helper macros and flush function that allow in-situ debug annotation of Perfetto tracks. This introduces a STR, INT and FLOAT variants to stack debug annotations into a temporary array and have COMMIT to push that to Perfetto. There's a maximum imposed limit of 128 entries in the array. Users shouldn't be concerned with allocating char string arrays as COMMIT will basically flush all the data in the temporary array to Perfetto. Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
This commit is contained in:
parent
414e85c22d
commit
940a2b03d9
3 changed files with 260 additions and 0 deletions
|
|
@ -151,6 +151,83 @@ util_perfetto_next_id(void)
|
|||
return p_atomic_inc_return(&util_perfetto_unique_id);
|
||||
}
|
||||
|
||||
static void
|
||||
util_perfetto_flush_debug_annotation(perfetto::EventContext *ctx,
|
||||
unsigned int nr_entries,
|
||||
struct weston_debug_annotation *annots)
|
||||
{
|
||||
if (nr_entries == 0)
|
||||
return;
|
||||
|
||||
for (unsigned int idx = 0; idx < nr_entries; idx++) {
|
||||
switch (annots[idx].type) {
|
||||
case WESTON_DEBUG_ANNOTATION_INT_VAL:
|
||||
ctx->AddDebugAnnotation(annots[idx].key, annots[idx].ivalue);
|
||||
break;
|
||||
case WESTON_DEBUG_ANNOTATION_FLOAT_VAL:
|
||||
ctx->AddDebugAnnotation(annots[idx].key, annots[idx].fvalue);
|
||||
break;
|
||||
case WESTON_DEBUG_ANNOTATION_STR_VAL:
|
||||
ctx->AddDebugAnnotation(annots[idx].key, annots[idx].svalue);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
util_perfetto_trace_commit_debug_annots(uint64_t id, const char *name,
|
||||
unsigned int nr_entries,
|
||||
struct weston_debug_annotation *annots)
|
||||
{
|
||||
if (id) {
|
||||
TRACE_EVENT_INSTANT(UTIL_PERFETTO_CATEGORY_DEFAULT_STR,
|
||||
nullptr,
|
||||
perfetto::Flow::ProcessScoped(id),
|
||||
[&](perfetto::EventContext ctx) {
|
||||
ctx.event()->set_name(name);
|
||||
util_perfetto_flush_debug_annotation(&ctx, nr_entries, annots);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
TRACE_EVENT_INSTANT(UTIL_PERFETTO_CATEGORY_DEFAULT_STR,
|
||||
nullptr,
|
||||
[&](perfetto::EventContext ctx) {
|
||||
ctx.event()->set_name(name);
|
||||
util_perfetto_flush_debug_annotation(&ctx, nr_entries, annots);
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
util_perfetto_trace_commit_annotate_func(const char *name, unsigned int nr_entries,
|
||||
struct weston_debug_annotation *annots)
|
||||
{
|
||||
TRACE_EVENT_BEGIN(UTIL_PERFETTO_CATEGORY_DEFAULT_STR,
|
||||
nullptr,
|
||||
[&](perfetto::EventContext ctx) {
|
||||
ctx.event()->set_name(name);
|
||||
util_perfetto_flush_debug_annotation(&ctx, nr_entries, annots);
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
util_perfetto_trace_commit_annotate_func_flow(uint64_t id, const char *name,
|
||||
unsigned int nr_entries,
|
||||
struct weston_debug_annotation *annots)
|
||||
{
|
||||
TRACE_EVENT_BEGIN(UTIL_PERFETTO_CATEGORY_DEFAULT_STR,
|
||||
nullptr,
|
||||
perfetto::Flow::ProcessScoped(id),
|
||||
[&](perfetto::EventContext ctx) {
|
||||
ctx.event()->set_name(name);
|
||||
util_perfetto_flush_debug_annotation(&ctx, nr_entries, annots);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
class UtilPerfettoObserver : public perfetto::TrackEventSessionObserver {
|
||||
public:
|
||||
UtilPerfettoObserver() { perfetto::TrackEvent::AddSessionObserver(this); }
|
||||
|
|
|
|||
|
|
@ -39,6 +39,22 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum weston_debug_annotation_type {
|
||||
WESTON_DEBUG_ANNOTATION_INT_VAL,
|
||||
WESTON_DEBUG_ANNOTATION_FLOAT_VAL,
|
||||
WESTON_DEBUG_ANNOTATION_STR_VAL,
|
||||
};
|
||||
|
||||
struct weston_debug_annotation {
|
||||
const char *key;
|
||||
enum weston_debug_annotation_type type;
|
||||
union {
|
||||
int ivalue;
|
||||
float fvalue;
|
||||
const char *svalue;
|
||||
};
|
||||
};
|
||||
|
||||
#ifdef HAVE_PERFETTO
|
||||
|
||||
extern int util_perfetto_tracing_state;
|
||||
|
|
@ -63,6 +79,15 @@ void util_perfetto_trace_full_begin(const char *name, uint64_t track_id, uint64_
|
|||
|
||||
void util_perfetto_trace_full_end(const char *name, uint64_t track_id, clockid_t clock, uint64_t timestamp);
|
||||
|
||||
void util_perfetto_trace_commit_debug_annots(uint64_t id, const char *name,
|
||||
unsigned int entries, struct weston_debug_annotation *annots);
|
||||
|
||||
void util_perfetto_trace_commit_annotate_func(const char *name,
|
||||
unsigned int entries, struct weston_debug_annotation *annots);
|
||||
|
||||
void util_perfetto_trace_commit_annotate_func_flow(uint64_t id, const char *name,
|
||||
unsigned int entries, struct weston_debug_annotation *annots);
|
||||
|
||||
uint64_t util_perfetto_next_id(void);
|
||||
|
||||
uint64_t util_perfetto_new_track(const char *name);
|
||||
|
|
@ -104,6 +129,27 @@ util_perfetto_trace_full_end(const char *name, uint64_t track_id, clockid_t cloc
|
|||
{
|
||||
}
|
||||
|
||||
static inline void
|
||||
util_perfetto_trace_commit_debug_annots(uint64_t id, const char *name,
|
||||
unsigned int entries,
|
||||
struct weston_debug_annotation *annots)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void
|
||||
util_perfetto_trace_commit_annotate_func(const char *name,
|
||||
unsigned int entries,
|
||||
struct weston_debug_annotation *annots)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void
|
||||
util_perfetto_trace_commit_annotate_func_flow(uint64_t id, const char *name,
|
||||
unsigned int entries,
|
||||
struct weston_debug_annotation *annots)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void util_perfetto_counter_set(const char *name, double value)
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#define WESTON_TRACE_H
|
||||
|
||||
#include "perfetto/u_perfetto.h"
|
||||
#include <string.h>
|
||||
|
||||
#if defined(HAVE_PERFETTO)
|
||||
|
||||
|
|
@ -28,6 +29,9 @@
|
|||
# endif
|
||||
#endif
|
||||
|
||||
/* maximum allowed debug annotations */
|
||||
#define WESTON_MAX_DEBUG_ANNOTS 128
|
||||
|
||||
/* note that util_perfetto_is_tracing_enabled always returns false until
|
||||
* util_perfetto_init is called
|
||||
*/
|
||||
|
|
@ -69,6 +73,53 @@
|
|||
clock, timestamp); \
|
||||
} while (0)
|
||||
|
||||
#define _WESTON_TRACE_BEGIN_ANNOTATION() \
|
||||
struct weston_debug_annotation __pd_annots[WESTON_MAX_DEBUG_ANNOTS]; \
|
||||
unsigned int __pd_i = 0
|
||||
|
||||
#define _WESTON_TRACE_ANNOTATE_ADD_INT(k, v) \
|
||||
weston_assert_u32_gt(NULL, WESTON_MAX_DEBUG_ANNOTS, __pd_i); \
|
||||
__pd_annots[__pd_i].type = WESTON_DEBUG_ANNOTATION_INT_VAL; \
|
||||
__pd_annots[__pd_i].ivalue = v; \
|
||||
__pd_annots[__pd_i].key = k; \
|
||||
__pd_i++
|
||||
|
||||
#define _WESTON_TRACE_ANNOTATE_ADD_FLOAT(k, v) \
|
||||
weston_assert_u32_gt(NULL, WESTON_MAX_DEBUG_ANNOTS, __pd_i); \
|
||||
__pd_annots[__pd_i].type = WESTON_DEBUG_ANNOTATION_FLOAT_VAL; \
|
||||
__pd_annots[__pd_i].fvalue = v; \
|
||||
__pd_annots[__pd_i].key = k; \
|
||||
__pd_i++
|
||||
|
||||
#define _WESTON_TRACE_ANNOTATE_ADD_STR(k, v) \
|
||||
weston_assert_u32_gt(NULL, WESTON_MAX_DEBUG_ANNOTS, __pd_i); \
|
||||
__pd_annots[__pd_i].type = WESTON_DEBUG_ANNOTATION_STR_VAL; \
|
||||
__pd_annots[__pd_i].svalue = v; \
|
||||
__pd_annots[__pd_i].key = k; \
|
||||
__pd_i++
|
||||
|
||||
#define _WESTON_TRACE_COMMIT_ANNOTATION(id, name) \
|
||||
do { \
|
||||
if (unlikely(util_perfetto_is_tracing_enabled())) { \
|
||||
_weston_trace_scope_annotate_commit(id, name, &__pd_i, __pd_annots); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* annotated funcs */
|
||||
#define _WESTON_TRACE_ANNOTATE_FUNC_BEGIN(name, nr_entries, annots) \
|
||||
do { \
|
||||
if (unlikely(util_perfetto_is_tracing_enabled())) { \
|
||||
util_perfetto_trace_commit_annotate_func(name, *nr_entries, annots); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define _WESTON_TRACE_ANNOTATE_FUNC_BEGIN_FLOW(name, id, nr_entries, annots) \
|
||||
do { \
|
||||
if (unlikely(util_perfetto_is_tracing_enabled())) { \
|
||||
util_perfetto_trace_commit_annotate_func_flow(id, name, *nr_entries, annots); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#if __has_attribute(cleanup) && __has_attribute(unused)
|
||||
|
||||
#define _WESTON_TRACE_SCOPE_VAR_CONCAT(name, suffix) name##suffix
|
||||
|
|
@ -92,6 +143,16 @@
|
|||
__attribute__((cleanup(_weston_trace_scope_end), unused)) = \
|
||||
_weston_trace_scope_flow_begin(name, id)
|
||||
|
||||
#define _WESTON_TRACE_ANNOTATE_FUNC(name) \
|
||||
int _WESTON_TRACE_SCOPE_VAR(__LINE__) \
|
||||
__attribute__((cleanup(_weston_trace_scope_end), unused)) = \
|
||||
_weston_trace_annotate_func_begin(name, &__pd_i, __pd_annots)
|
||||
|
||||
#define _WESTON_TRACE_ANNOTATE_FUNC_FLOW(id, name) \
|
||||
int _WESTON_TRACE_SCOPE_VAR(__LINE__) \
|
||||
__attribute__((cleanup(_weston_trace_scope_end), unused)) = \
|
||||
_weston_trace_annotate_func_begin_flow(name, id, &__pd_i, __pd_annots)
|
||||
|
||||
static inline int
|
||||
_weston_trace_scope_begin(const char *name)
|
||||
{
|
||||
|
|
@ -108,6 +169,53 @@ _weston_trace_scope_flow_begin(const char *name, uint64_t *id)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
_weston_trace_scope_annotate_commit(uint64_t *id, const char *name,
|
||||
unsigned int *nr_entries,
|
||||
struct weston_debug_annotation *annots)
|
||||
{
|
||||
if (id && *id == 0) {
|
||||
*id = util_perfetto_next_id();
|
||||
util_perfetto_trace_commit_debug_annots(*id, name, *nr_entries, annots);
|
||||
goto reset_entries;
|
||||
}
|
||||
|
||||
util_perfetto_trace_commit_debug_annots(0, name, *nr_entries, annots);
|
||||
|
||||
/* reset the array and counter */
|
||||
reset_entries:
|
||||
memset(annots, 0, sizeof(struct weston_debug_annotation) * *nr_entries);
|
||||
*nr_entries = 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
_weston_trace_annotate_func_begin(const char *name, unsigned int *nr_entries,
|
||||
struct weston_debug_annotation *annots)
|
||||
{
|
||||
_WESTON_TRACE_ANNOTATE_FUNC_BEGIN(name, nr_entries, annots);
|
||||
|
||||
/* reset the array and counter */
|
||||
memset(annots, 0, sizeof(struct weston_debug_annotation) * *nr_entries);
|
||||
*nr_entries = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
_weston_trace_annotate_func_begin_flow(const char *name, uint64_t *id,
|
||||
unsigned int *nr_entries,
|
||||
struct weston_debug_annotation *annots)
|
||||
{
|
||||
if (*id == 0)
|
||||
*id = util_perfetto_next_id();
|
||||
|
||||
_WESTON_TRACE_ANNOTATE_FUNC_BEGIN_FLOW(name, *id, nr_entries, annots);
|
||||
|
||||
/* reset the array and counter */
|
||||
memset(annots, 0, sizeof(struct weston_debug_annotation) * *nr_entries);
|
||||
*nr_entries = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
_weston_trace_scope_end(int *scope)
|
||||
{
|
||||
|
|
@ -130,6 +238,14 @@ _weston_trace_scope_end(int *scope)
|
|||
#define _WESTON_TRACE_TIMESTAMP_BEGIN(name, track_id, flow_id, clock, timestamp)
|
||||
#define _WESTON_TRACE_TIMESTAMP_END(name, track_id, clock, timestamp)
|
||||
|
||||
#define _WESTON_TRACE_BEGIN_ANNOTATION()
|
||||
#define _WESTON_TRACE_COMMIT_ANNOTATION(id, name)
|
||||
#define _WESTON_TRACE_ANNOTATE_ADD_INT(k, v)
|
||||
#define _WESTON_TRACE_ANNOTATE_ADD_FLOAT(k, v)
|
||||
#define _WESTON_TRACE_ANNOTATE_ADD_STR(k, v)
|
||||
#define _WESTON_TRACE_ANNOTATE_FUNC()
|
||||
#define _WESTON_TRACE_ANNOTATE_FUNC_FLOW(id, name)
|
||||
|
||||
#endif /* HAVE_PERFETTO */
|
||||
|
||||
#define WESTON_TRACE_SCOPE(name) _WESTON_TRACE_SCOPE(name)
|
||||
|
|
@ -142,4 +258,25 @@ _weston_trace_scope_end(int *scope)
|
|||
#define WESTON_TRACE_TIMESTAMP_END(name, track_id, clock, timestamp) \
|
||||
_WESTON_TRACE_TIMESTAMP_END(name, track_id, clock, timestamp)
|
||||
|
||||
#define WESTON_TRACE_BEGIN_ANNOTATION() \
|
||||
_WESTON_TRACE_BEGIN_ANNOTATION()
|
||||
|
||||
#define WESTON_TRACE_ANNOTATE_ADD_INT(k, v) \
|
||||
_WESTON_TRACE_ANNOTATE_ADD_INT(k, v)
|
||||
|
||||
#define WESTON_TRACE_ANNOTATE_ADD_FLOAT(k, v) \
|
||||
_WESTON_TRACE_ANNOTATE_ADD_FLOAT(k, v)
|
||||
|
||||
#define WESTON_TRACE_ANNOTATE_ADD_STR(k, v) \
|
||||
_WESTON_TRACE_ANNOTATE_ADD_STR(k, v)
|
||||
|
||||
#define WESTON_TRACE_COMMIT_ANNOTATION(id) \
|
||||
_WESTON_TRACE_COMMIT_ANNOTATION(id, __func__)
|
||||
|
||||
#define WESTON_TRACE_ANNOTATE_FUNC() \
|
||||
_WESTON_TRACE_ANNOTATE_FUNC(__func__)
|
||||
|
||||
#define WESTON_TRACE_ANNOTATE_FUNC_FLOW(id) \
|
||||
_WESTON_TRACE_ANNOTATE_FUNC_FLOW(id, __func__)
|
||||
|
||||
#endif /* WESTON_TRACE_H */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue