1 /**************************************************************************
2 *
3 * Copyright (C) 2019 Chromium.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 * OTHER DEALINGS IN THE SOFTWARE.
22 *
23 **************************************************************************/
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include "virgl_util.h"
30
31 #include <errno.h>
32 #ifdef HAVE_EVENTFD_H
33 #include <sys/eventfd.h>
34 #endif
35 #include <unistd.h>
36
37 #include "util/u_pointer.h"
38
39 #include <stdarg.h>
40 #include <stdio.h>
41
42 #ifdef HAVE_CONFIG_H
43 #include "config.h"
44 #endif
45
46 #if ENABLE_TRACING == TRACE_WITH_PERFETTO
47 #include <vperfetto-min.h>
48 #endif
49
50 #if ENABLE_TRACING == TRACE_WITH_STDERR
51 #include <stdio.h>
52 #endif
53
hash_func_u32(void * key)54 unsigned hash_func_u32(void *key)
55 {
56 intptr_t ip = pointer_to_intptr(key);
57 return (unsigned)(ip & 0xffffffff);
58 }
59
compare_func(void * key1,void * key2)60 int compare_func(void *key1, void *key2)
61 {
62 if (key1 < key2)
63 return -1;
64 if (key1 > key2)
65 return 1;
66 else
67 return 0;
68 }
69
has_eventfd(void)70 bool has_eventfd(void)
71 {
72 #ifdef HAVE_EVENTFD_H
73 return true;
74 #else
75 return false;
76 #endif
77 }
78
create_eventfd(unsigned int initval)79 int create_eventfd(unsigned int initval)
80 {
81 #ifdef HAVE_EVENTFD_H
82 return eventfd(initval, EFD_CLOEXEC | EFD_NONBLOCK);
83 #else
84 return -1;
85 #endif
86 }
87
write_eventfd(int fd,uint64_t val)88 int write_eventfd(int fd, uint64_t val)
89 {
90 const char *buf = (const char *)&val;
91 size_t count = sizeof(val);
92 ssize_t ret = 0;
93
94 while (count) {
95 ret = write(fd, buf, count);
96 if (ret < 0) {
97 if (errno == EINTR)
98 continue;
99 break;
100 }
101 count -= ret;
102 buf += ret;
103 }
104
105 return count ? -1 : 0;
106 }
107
flush_eventfd(int fd)108 void flush_eventfd(int fd)
109 {
110 ssize_t len;
111 uint64_t value;
112 do {
113 len = read(fd, &value, sizeof(value));
114 } while ((len == -1 && errno == EINTR) || len == sizeof(value));
115 }
116
117 #if ENABLE_TRACING == TRACE_WITH_PERCETTO
PERCETTO_CATEGORY_DEFINE(VIRGL_PERCETTO_CATEGORIES)118 PERCETTO_CATEGORY_DEFINE(VIRGL_PERCETTO_CATEGORIES)
119
120 void trace_init(void)
121 {
122 PERCETTO_INIT(PERCETTO_CLOCK_DONT_CARE);
123 }
124 #endif
125
126 #if ENABLE_TRACING == TRACE_WITH_PERFETTO
trace_init(void)127 void trace_init(void)
128 {
129 struct vperfetto_min_config config = {
130 .init_flags = VPERFETTO_INIT_FLAG_USE_SYSTEM_BACKEND,
131 .filename = NULL,
132 .shmem_size_hint_kb = 32 * 1024,
133 };
134
135 vperfetto_min_startTracing(&config);
136 }
137
trace_begin(const char * scope)138 const char *trace_begin(const char *scope)
139 {
140 vperfetto_min_beginTrackEvent_VMM(scope);
141 return scope;
142 }
143
trace_end(const char ** dummy)144 void trace_end(const char **dummy)
145 {
146 (void)dummy;
147 vperfetto_min_endTrackEvent_VMM();
148 }
149 #endif
150
151 #if ENABLE_TRACING == TRACE_WITH_STDERR
152 static int nesting_depth = 0;
trace_init(void)153 void trace_init(void)
154 {
155 }
156
trace_begin(const char * scope)157 const char *trace_begin(const char *scope)
158 {
159 for (int i = 0; i < nesting_depth; ++i)
160 fprintf(stderr, " ");
161
162 fprintf(stderr, "ENTER:%s\n", scope);
163 nesting_depth++;
164
165 return scope;
166 }
167
trace_end(const char ** func_name)168 void trace_end(const char **func_name)
169 {
170 --nesting_depth;
171 for (int i = 0; i < nesting_depth; ++i)
172 fprintf(stderr, " ");
173 fprintf(stderr, "LEAVE %s\n", *func_name);
174 }
175 #endif
176