1*bbecb9d1SAndroid Build Coastguard Worker /**************************************************************************
2*bbecb9d1SAndroid Build Coastguard Worker *
3*bbecb9d1SAndroid Build Coastguard Worker * Copyright (C) 2019 Chromium.
4*bbecb9d1SAndroid Build Coastguard Worker *
5*bbecb9d1SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
6*bbecb9d1SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
7*bbecb9d1SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
8*bbecb9d1SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9*bbecb9d1SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
10*bbecb9d1SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
11*bbecb9d1SAndroid Build Coastguard Worker *
12*bbecb9d1SAndroid Build Coastguard Worker * The above copyright notice and this permission notice shall be included
13*bbecb9d1SAndroid Build Coastguard Worker * in all copies or substantial portions of the Software.
14*bbecb9d1SAndroid Build Coastguard Worker *
15*bbecb9d1SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16*bbecb9d1SAndroid Build Coastguard Worker * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*bbecb9d1SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18*bbecb9d1SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19*bbecb9d1SAndroid Build Coastguard Worker * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20*bbecb9d1SAndroid Build Coastguard Worker * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21*bbecb9d1SAndroid Build Coastguard Worker * OTHER DEALINGS IN THE SOFTWARE.
22*bbecb9d1SAndroid Build Coastguard Worker *
23*bbecb9d1SAndroid Build Coastguard Worker **************************************************************************/
24*bbecb9d1SAndroid Build Coastguard Worker
25*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_CONFIG_H
26*bbecb9d1SAndroid Build Coastguard Worker #include "config.h"
27*bbecb9d1SAndroid Build Coastguard Worker #endif
28*bbecb9d1SAndroid Build Coastguard Worker
29*bbecb9d1SAndroid Build Coastguard Worker #include "virgl_util.h"
30*bbecb9d1SAndroid Build Coastguard Worker
31*bbecb9d1SAndroid Build Coastguard Worker #include <errno.h>
32*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_EVENTFD_H
33*bbecb9d1SAndroid Build Coastguard Worker #include <sys/eventfd.h>
34*bbecb9d1SAndroid Build Coastguard Worker #endif
35*bbecb9d1SAndroid Build Coastguard Worker #include <unistd.h>
36*bbecb9d1SAndroid Build Coastguard Worker
37*bbecb9d1SAndroid Build Coastguard Worker #include "util/os_misc.h"
38*bbecb9d1SAndroid Build Coastguard Worker #include "util/u_pointer.h"
39*bbecb9d1SAndroid Build Coastguard Worker
40*bbecb9d1SAndroid Build Coastguard Worker #include <assert.h>
41*bbecb9d1SAndroid Build Coastguard Worker #include <stdarg.h>
42*bbecb9d1SAndroid Build Coastguard Worker #include <stdio.h>
43*bbecb9d1SAndroid Build Coastguard Worker
44*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_CONFIG_H
45*bbecb9d1SAndroid Build Coastguard Worker #include "config.h"
46*bbecb9d1SAndroid Build Coastguard Worker #endif
47*bbecb9d1SAndroid Build Coastguard Worker
48*bbecb9d1SAndroid Build Coastguard Worker #if ENABLE_TRACING == TRACE_WITH_PERFETTO
49*bbecb9d1SAndroid Build Coastguard Worker #include <vperfetto-min.h>
50*bbecb9d1SAndroid Build Coastguard Worker #endif
51*bbecb9d1SAndroid Build Coastguard Worker
52*bbecb9d1SAndroid Build Coastguard Worker #if ENABLE_TRACING == TRACE_WITH_STDERR
53*bbecb9d1SAndroid Build Coastguard Worker #include <stdio.h>
54*bbecb9d1SAndroid Build Coastguard Worker #endif
55*bbecb9d1SAndroid Build Coastguard Worker
hash_func_u32(const void * key)56*bbecb9d1SAndroid Build Coastguard Worker uint32_t hash_func_u32(const void *key)
57*bbecb9d1SAndroid Build Coastguard Worker {
58*bbecb9d1SAndroid Build Coastguard Worker intptr_t ip = pointer_to_intptr(key);
59*bbecb9d1SAndroid Build Coastguard Worker return (uint32_t)(ip & 0xffffffff);
60*bbecb9d1SAndroid Build Coastguard Worker }
61*bbecb9d1SAndroid Build Coastguard Worker
equal_func(const void * key1,const void * key2)62*bbecb9d1SAndroid Build Coastguard Worker bool equal_func(const void *key1, const void *key2)
63*bbecb9d1SAndroid Build Coastguard Worker {
64*bbecb9d1SAndroid Build Coastguard Worker return key1 == key2;
65*bbecb9d1SAndroid Build Coastguard Worker }
66*bbecb9d1SAndroid Build Coastguard Worker
has_eventfd(void)67*bbecb9d1SAndroid Build Coastguard Worker bool has_eventfd(void)
68*bbecb9d1SAndroid Build Coastguard Worker {
69*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_EVENTFD_H
70*bbecb9d1SAndroid Build Coastguard Worker return true;
71*bbecb9d1SAndroid Build Coastguard Worker #else
72*bbecb9d1SAndroid Build Coastguard Worker return false;
73*bbecb9d1SAndroid Build Coastguard Worker #endif
74*bbecb9d1SAndroid Build Coastguard Worker }
75*bbecb9d1SAndroid Build Coastguard Worker
create_eventfd(unsigned int initval)76*bbecb9d1SAndroid Build Coastguard Worker int create_eventfd(unsigned int initval)
77*bbecb9d1SAndroid Build Coastguard Worker {
78*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_EVENTFD_H
79*bbecb9d1SAndroid Build Coastguard Worker return eventfd(initval, EFD_CLOEXEC | EFD_NONBLOCK);
80*bbecb9d1SAndroid Build Coastguard Worker #else
81*bbecb9d1SAndroid Build Coastguard Worker (void)initval;
82*bbecb9d1SAndroid Build Coastguard Worker return -1;
83*bbecb9d1SAndroid Build Coastguard Worker #endif
84*bbecb9d1SAndroid Build Coastguard Worker }
85*bbecb9d1SAndroid Build Coastguard Worker
write_eventfd(int fd,uint64_t val)86*bbecb9d1SAndroid Build Coastguard Worker int write_eventfd(int fd, uint64_t val)
87*bbecb9d1SAndroid Build Coastguard Worker {
88*bbecb9d1SAndroid Build Coastguard Worker const char *buf = (const char *)&val;
89*bbecb9d1SAndroid Build Coastguard Worker size_t count = sizeof(val);
90*bbecb9d1SAndroid Build Coastguard Worker ssize_t ret = 0;
91*bbecb9d1SAndroid Build Coastguard Worker
92*bbecb9d1SAndroid Build Coastguard Worker while (count) {
93*bbecb9d1SAndroid Build Coastguard Worker ret = write(fd, buf, count);
94*bbecb9d1SAndroid Build Coastguard Worker if (ret < 0) {
95*bbecb9d1SAndroid Build Coastguard Worker if (errno == EINTR)
96*bbecb9d1SAndroid Build Coastguard Worker continue;
97*bbecb9d1SAndroid Build Coastguard Worker break;
98*bbecb9d1SAndroid Build Coastguard Worker }
99*bbecb9d1SAndroid Build Coastguard Worker count -= ret;
100*bbecb9d1SAndroid Build Coastguard Worker buf += ret;
101*bbecb9d1SAndroid Build Coastguard Worker }
102*bbecb9d1SAndroid Build Coastguard Worker
103*bbecb9d1SAndroid Build Coastguard Worker return count ? -1 : 0;
104*bbecb9d1SAndroid Build Coastguard Worker }
105*bbecb9d1SAndroid Build Coastguard Worker
flush_eventfd(int fd)106*bbecb9d1SAndroid Build Coastguard Worker void flush_eventfd(int fd)
107*bbecb9d1SAndroid Build Coastguard Worker {
108*bbecb9d1SAndroid Build Coastguard Worker ssize_t len;
109*bbecb9d1SAndroid Build Coastguard Worker uint64_t value;
110*bbecb9d1SAndroid Build Coastguard Worker do {
111*bbecb9d1SAndroid Build Coastguard Worker len = read(fd, &value, sizeof(value));
112*bbecb9d1SAndroid Build Coastguard Worker } while ((len == -1 && errno == EINTR) || len == sizeof(value));
113*bbecb9d1SAndroid Build Coastguard Worker }
114*bbecb9d1SAndroid Build Coastguard Worker
115*bbecb9d1SAndroid Build Coastguard Worker static
virgl_default_logger(const char * fmt,va_list va)116*bbecb9d1SAndroid Build Coastguard Worker void virgl_default_logger(const char *fmt, va_list va)
117*bbecb9d1SAndroid Build Coastguard Worker {
118*bbecb9d1SAndroid Build Coastguard Worker static FILE* fp = NULL;
119*bbecb9d1SAndroid Build Coastguard Worker if (NULL == fp) {
120*bbecb9d1SAndroid Build Coastguard Worker const char* log = getenv("VIRGL_LOG_FILE");
121*bbecb9d1SAndroid Build Coastguard Worker if (log) {
122*bbecb9d1SAndroid Build Coastguard Worker char *log_prefix = strdup(log);
123*bbecb9d1SAndroid Build Coastguard Worker char *log_suffix = strstr(log_prefix, "%PID%");
124*bbecb9d1SAndroid Build Coastguard Worker if (log_suffix) {
125*bbecb9d1SAndroid Build Coastguard Worker *log_suffix = 0;
126*bbecb9d1SAndroid Build Coastguard Worker log_suffix += 5;
127*bbecb9d1SAndroid Build Coastguard Worker int len = strlen(log) + 32;
128*bbecb9d1SAndroid Build Coastguard Worker char *name = malloc(len);
129*bbecb9d1SAndroid Build Coastguard Worker snprintf(name, len, "%s%d%s", log_prefix, getpid(), log_suffix);
130*bbecb9d1SAndroid Build Coastguard Worker fp = fopen(name, "a");
131*bbecb9d1SAndroid Build Coastguard Worker free(name);
132*bbecb9d1SAndroid Build Coastguard Worker } else {
133*bbecb9d1SAndroid Build Coastguard Worker fp = fopen(log, "a");
134*bbecb9d1SAndroid Build Coastguard Worker }
135*bbecb9d1SAndroid Build Coastguard Worker free(log_prefix);
136*bbecb9d1SAndroid Build Coastguard Worker if (NULL == fp) {
137*bbecb9d1SAndroid Build Coastguard Worker fprintf(stderr, "Can't open %s\n", log);
138*bbecb9d1SAndroid Build Coastguard Worker fp = stderr;
139*bbecb9d1SAndroid Build Coastguard Worker }
140*bbecb9d1SAndroid Build Coastguard Worker } else {
141*bbecb9d1SAndroid Build Coastguard Worker fp = stderr;
142*bbecb9d1SAndroid Build Coastguard Worker }
143*bbecb9d1SAndroid Build Coastguard Worker }
144*bbecb9d1SAndroid Build Coastguard Worker vfprintf(fp, fmt, va);
145*bbecb9d1SAndroid Build Coastguard Worker fflush(fp);
146*bbecb9d1SAndroid Build Coastguard Worker }
147*bbecb9d1SAndroid Build Coastguard Worker
148*bbecb9d1SAndroid Build Coastguard Worker static
virgl_null_logger(UNUSED const char * fmt,UNUSED va_list va)149*bbecb9d1SAndroid Build Coastguard Worker void virgl_null_logger(UNUSED const char *fmt, UNUSED va_list va)
150*bbecb9d1SAndroid Build Coastguard Worker {
151*bbecb9d1SAndroid Build Coastguard Worker }
152*bbecb9d1SAndroid Build Coastguard Worker
153*bbecb9d1SAndroid Build Coastguard Worker static virgl_debug_callback_type virgl_logger = virgl_default_logger;
154*bbecb9d1SAndroid Build Coastguard Worker
virgl_log_set_logger(virgl_debug_callback_type logger)155*bbecb9d1SAndroid Build Coastguard Worker virgl_debug_callback_type virgl_log_set_logger(virgl_debug_callback_type logger)
156*bbecb9d1SAndroid Build Coastguard Worker {
157*bbecb9d1SAndroid Build Coastguard Worker virgl_debug_callback_type old = virgl_logger;
158*bbecb9d1SAndroid Build Coastguard Worker
159*bbecb9d1SAndroid Build Coastguard Worker /* virgl_null_logger is internal */
160*bbecb9d1SAndroid Build Coastguard Worker if (old == virgl_null_logger)
161*bbecb9d1SAndroid Build Coastguard Worker old = NULL;
162*bbecb9d1SAndroid Build Coastguard Worker if (!logger)
163*bbecb9d1SAndroid Build Coastguard Worker logger = virgl_null_logger;
164*bbecb9d1SAndroid Build Coastguard Worker
165*bbecb9d1SAndroid Build Coastguard Worker virgl_logger = logger;
166*bbecb9d1SAndroid Build Coastguard Worker return old;
167*bbecb9d1SAndroid Build Coastguard Worker }
168*bbecb9d1SAndroid Build Coastguard Worker
virgl_logv(const char * fmt,va_list va)169*bbecb9d1SAndroid Build Coastguard Worker void virgl_logv(const char *fmt, va_list va)
170*bbecb9d1SAndroid Build Coastguard Worker {
171*bbecb9d1SAndroid Build Coastguard Worker assert(virgl_logger);
172*bbecb9d1SAndroid Build Coastguard Worker virgl_logger(fmt, va);
173*bbecb9d1SAndroid Build Coastguard Worker }
174*bbecb9d1SAndroid Build Coastguard Worker
175*bbecb9d1SAndroid Build Coastguard Worker #if ENABLE_TRACING == TRACE_WITH_PERCETTO
PERCETTO_CATEGORY_DEFINE(VIRGL_PERCETTO_CATEGORIES)176*bbecb9d1SAndroid Build Coastguard Worker PERCETTO_CATEGORY_DEFINE(VIRGL_PERCETTO_CATEGORIES)
177*bbecb9d1SAndroid Build Coastguard Worker
178*bbecb9d1SAndroid Build Coastguard Worker void trace_init(void)
179*bbecb9d1SAndroid Build Coastguard Worker {
180*bbecb9d1SAndroid Build Coastguard Worker PERCETTO_INIT(PERCETTO_CLOCK_DONT_CARE);
181*bbecb9d1SAndroid Build Coastguard Worker }
182*bbecb9d1SAndroid Build Coastguard Worker #endif
183*bbecb9d1SAndroid Build Coastguard Worker
184*bbecb9d1SAndroid Build Coastguard Worker #if ENABLE_TRACING == TRACE_WITH_PERFETTO
on_tracing_state_change(bool enabled)185*bbecb9d1SAndroid Build Coastguard Worker static void on_tracing_state_change(bool enabled) {
186*bbecb9d1SAndroid Build Coastguard Worker virgl_log("%s: tracing state change: %d\n", __func__, enabled);
187*bbecb9d1SAndroid Build Coastguard Worker }
188*bbecb9d1SAndroid Build Coastguard Worker
trace_init(void)189*bbecb9d1SAndroid Build Coastguard Worker void trace_init(void)
190*bbecb9d1SAndroid Build Coastguard Worker {
191*bbecb9d1SAndroid Build Coastguard Worker struct vperfetto_min_config config = {
192*bbecb9d1SAndroid Build Coastguard Worker .on_tracing_state_change = on_tracing_state_change,
193*bbecb9d1SAndroid Build Coastguard Worker .init_flags = VPERFETTO_INIT_FLAG_USE_SYSTEM_BACKEND,
194*bbecb9d1SAndroid Build Coastguard Worker .filename = NULL,
195*bbecb9d1SAndroid Build Coastguard Worker .shmem_size_hint_kb = 32 * 1024,
196*bbecb9d1SAndroid Build Coastguard Worker };
197*bbecb9d1SAndroid Build Coastguard Worker
198*bbecb9d1SAndroid Build Coastguard Worker vperfetto_min_startTracing(&config);
199*bbecb9d1SAndroid Build Coastguard Worker }
200*bbecb9d1SAndroid Build Coastguard Worker
trace_begin(const char * scope)201*bbecb9d1SAndroid Build Coastguard Worker const char *trace_begin(const char *scope)
202*bbecb9d1SAndroid Build Coastguard Worker {
203*bbecb9d1SAndroid Build Coastguard Worker vperfetto_min_beginTrackEvent_VMM(scope);
204*bbecb9d1SAndroid Build Coastguard Worker return scope;
205*bbecb9d1SAndroid Build Coastguard Worker }
206*bbecb9d1SAndroid Build Coastguard Worker
trace_end(const char ** dummy)207*bbecb9d1SAndroid Build Coastguard Worker void trace_end(const char **dummy)
208*bbecb9d1SAndroid Build Coastguard Worker {
209*bbecb9d1SAndroid Build Coastguard Worker (void)dummy;
210*bbecb9d1SAndroid Build Coastguard Worker vperfetto_min_endTrackEvent_VMM();
211*bbecb9d1SAndroid Build Coastguard Worker }
212*bbecb9d1SAndroid Build Coastguard Worker #endif
213*bbecb9d1SAndroid Build Coastguard Worker
214*bbecb9d1SAndroid Build Coastguard Worker #if ENABLE_TRACING == TRACE_WITH_STDERR
215*bbecb9d1SAndroid Build Coastguard Worker static int nesting_depth = 0;
trace_init(void)216*bbecb9d1SAndroid Build Coastguard Worker void trace_init(void)
217*bbecb9d1SAndroid Build Coastguard Worker {
218*bbecb9d1SAndroid Build Coastguard Worker }
219*bbecb9d1SAndroid Build Coastguard Worker
trace_begin(const char * scope)220*bbecb9d1SAndroid Build Coastguard Worker const char *trace_begin(const char *scope)
221*bbecb9d1SAndroid Build Coastguard Worker {
222*bbecb9d1SAndroid Build Coastguard Worker for (int i = 0; i < nesting_depth; ++i)
223*bbecb9d1SAndroid Build Coastguard Worker fprintf(stderr, " ");
224*bbecb9d1SAndroid Build Coastguard Worker
225*bbecb9d1SAndroid Build Coastguard Worker fprintf(stderr, "ENTER:%s\n", scope);
226*bbecb9d1SAndroid Build Coastguard Worker nesting_depth++;
227*bbecb9d1SAndroid Build Coastguard Worker
228*bbecb9d1SAndroid Build Coastguard Worker return scope;
229*bbecb9d1SAndroid Build Coastguard Worker }
230*bbecb9d1SAndroid Build Coastguard Worker
trace_end(const char ** func_name)231*bbecb9d1SAndroid Build Coastguard Worker void trace_end(const char **func_name)
232*bbecb9d1SAndroid Build Coastguard Worker {
233*bbecb9d1SAndroid Build Coastguard Worker --nesting_depth;
234*bbecb9d1SAndroid Build Coastguard Worker for (int i = 0; i < nesting_depth; ++i)
235*bbecb9d1SAndroid Build Coastguard Worker fprintf(stderr, " ");
236*bbecb9d1SAndroid Build Coastguard Worker fprintf(stderr, "LEAVE %s\n", *func_name);
237*bbecb9d1SAndroid Build Coastguard Worker }
238*bbecb9d1SAndroid Build Coastguard Worker #endif
239