1 /* SPDX-License-Identifier: Apache-2.0 OR MIT */
2 /*
3 * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
4 */
5
6 #define MODULE_TAG "mpp_trace"
7
8 #include <fcntl.h>
9 #include <stdarg.h>
10
11 #include "mpp_log.h"
12 #include "mpp_mem.h"
13 #include "mpp_common.h"
14 #include "mpp_singleton.h"
15
16 #include "mpp_trace.h"
17
18 #define ATRACE_MESSAGE_LENGTH 256
19
20 #define get_srv_trace() \
21 ({ \
22 MppTraceSrv *__tmp; \
23 if (!srv_trace) { \
24 mpp_trace_srv_init(); \
25 } \
26 if (srv_trace) { \
27 __tmp = srv_trace; \
28 } else { \
29 mpp_err("mpp trace srv not init at %s : %s\n", __FUNCTION__); \
30 __tmp = NULL; \
31 } \
32 __tmp; \
33 })
34
35 typedef struct MppTraceSrv_t {
36 const char *name;
37 rk_s32 fd;
38 } MppTraceSrv;
39
40 static MppTraceSrv *srv_trace = NULL;
41
mpp_trace_srv_init()42 static void mpp_trace_srv_init()
43 {
44 static const char *ftrace_paths[] = {
45 "/sys/kernel/debug/tracing/trace_marker",
46 "/debug/tracing/trace_marker",
47 "/debugfs/tracing/trace_marker",
48 };
49 MppTraceSrv *srv = srv_trace;
50 rk_u32 i;
51
52 if (srv)
53 return;
54
55 srv = mpp_calloc(MppTraceSrv, 1);
56 if (!srv) {
57 mpp_err_f("failed to allocate trace service\n");
58 return;
59 }
60
61 srv_trace = srv;
62 srv->fd = -1;
63
64 for (i = 0; i < MPP_ARRAY_ELEMS(ftrace_paths); i++) {
65 if (!access(ftrace_paths[i], F_OK)) {
66 rk_s32 fd = open(ftrace_paths[i], O_WRONLY | O_CLOEXEC);
67
68 if (fd >= 0) {
69 srv->fd = fd;
70 srv->name = ftrace_paths[i];
71 break;
72 }
73 }
74 }
75 }
76
mpp_trace_srv_deinit()77 static void mpp_trace_srv_deinit()
78 {
79 MppTraceSrv *srv = srv_trace;
80
81 if (srv) {
82 if (srv->fd >= 0) {
83 close(srv->fd);
84 srv->fd = -1;
85 }
86 mpp_free(srv);
87 }
88
89 srv_trace = NULL;
90 }
91
mpp_trace_write(rk_s32 fd,const char * fmt,...)92 static void mpp_trace_write(rk_s32 fd, const char *fmt, ...)
93 {
94 char buf[ATRACE_MESSAGE_LENGTH];
95 va_list ap;
96 rk_s32 len;
97
98 va_start(ap, fmt);
99 len = vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
100 va_end(ap);
101
102 (void)!write(fd, buf, len);
103 }
104
mpp_trace_begin(const char * name)105 void mpp_trace_begin(const char* name)
106 {
107 MppTraceSrv *srv = get_srv_trace();
108
109 if (srv && srv->fd >= 0)
110 mpp_trace_write(srv->fd, "B|%d|%s", getpid(), name);
111 }
112
mpp_trace_end(const char * name)113 void mpp_trace_end(const char* name)
114 {
115 MppTraceSrv *srv = get_srv_trace();
116
117 if (srv && srv->fd >= 0)
118 mpp_trace_write(srv->fd, "E|%d|%s", getpid(), name);
119 }
120
mpp_trace_async_begin(const char * name,rk_s32 cookie)121 void mpp_trace_async_begin(const char* name, rk_s32 cookie)
122 {
123 MppTraceSrv *srv = get_srv_trace();
124
125 if (srv && srv->fd >= 0)
126 mpp_trace_write(srv->fd, "S|%d|%s|%d", getpid(), name, cookie);
127 }
128
mpp_trace_async_end(const char * name,rk_s32 cookie)129 void mpp_trace_async_end(const char* name, rk_s32 cookie)
130 {
131 MppTraceSrv *srv = get_srv_trace();
132
133 if (srv && srv->fd >= 0)
134 mpp_trace_write(srv->fd, "F|%d|%s|%d", getpid(), name, cookie);
135 }
136
mpp_trace_int32(const char * name,rk_s32 value)137 void mpp_trace_int32(const char* name, rk_s32 value)
138 {
139 MppTraceSrv *srv = get_srv_trace();
140
141 if (srv && srv->fd >= 0)
142 mpp_trace_write(srv->fd, "C|%d|%s|%d", getpid(), name, value);
143 }
144
mpp_trace_int64(const char * name,RK_S64 value)145 void mpp_trace_int64(const char* name, RK_S64 value)
146 {
147 MppTraceSrv *srv = get_srv_trace();
148
149 if (srv && srv->fd >= 0)
150 mpp_trace_write(srv->fd, "C|%d|%s|%lld", getpid(), name, value);
151 }
152
153 MPP_SINGLETON(MPP_SGLN_TRACE, mpp_trace, mpp_trace_srv_init, mpp_trace_srv_deinit)
154