1 /*
2 * Copyright 2019 Google LLC
3 * SPDX-License-Identifier: MIT
4 *
5 * based in part on anv and radv which are:
6 * Copyright © 2015 Intel Corporation
7 * Copyright © 2016 Red Hat.
8 * Copyright © 2016 Bas Nieuwenhuizen
9 */
10
11 #include "vn_common.h"
12
13 #include <stdarg.h>
14
15 #include "util/debug.h"
16 #include "util/log.h"
17 #include "util/os_misc.h"
18 #include "vk_enum_to_str.h"
19
20 static const struct debug_control vn_debug_options[] = {
21 { "init", VN_DEBUG_INIT },
22 { "result", VN_DEBUG_RESULT },
23 { "vtest", VN_DEBUG_VTEST },
24 { "wsi", VN_DEBUG_WSI },
25 { NULL, 0 },
26 };
27
28 uint64_t vn_debug;
29
30 static void
vn_debug_init_once(void)31 vn_debug_init_once(void)
32 {
33 vn_debug = parse_debug_string(os_get_option("VN_DEBUG"), vn_debug_options);
34 }
35
36 void
vn_debug_init(void)37 vn_debug_init(void)
38 {
39 static once_flag once = ONCE_FLAG_INIT;
40 call_once(&once, vn_debug_init_once);
41 }
42
43 void
vn_trace_init(void)44 vn_trace_init(void)
45 {
46 #ifdef ANDROID
47 atrace_init();
48 #endif
49 }
50
51 void
vn_log(struct vn_instance * instance,const char * format,...)52 vn_log(struct vn_instance *instance, const char *format, ...)
53 {
54 va_list ap;
55
56 va_start(ap, format);
57 mesa_log_v(MESA_LOG_DEBUG, "MESA-VIRTIO", format, ap);
58 va_end(ap);
59
60 /* instance may be NULL or partially initialized */
61 }
62
63 VkResult
vn_log_result(struct vn_instance * instance,VkResult result,const char * where)64 vn_log_result(struct vn_instance *instance,
65 VkResult result,
66 const char *where)
67 {
68 vn_log(instance, "%s: %s", where, vk_Result_to_str(result));
69 return result;
70 }
71
72 void
vn_relax(uint32_t * iter,const char * reason)73 vn_relax(uint32_t *iter, const char *reason)
74 {
75 /* Yield for the first 2^busy_wait_order times and then sleep for
76 * base_sleep_us microseconds for the same number of times. After that,
77 * keep doubling both sleep length and count.
78 */
79 const uint32_t busy_wait_order = 4;
80 const uint32_t base_sleep_us = 10;
81 const uint32_t warn_order = 12;
82
83 (*iter)++;
84 if (*iter < (1 << busy_wait_order)) {
85 thrd_yield();
86 return;
87 }
88
89 /* warn occasionally if we have slept at least 1.28ms for 2048 times (plus
90 * another 2047 shorter sleeps)
91 */
92 if (unlikely(*iter % (1 << warn_order) == 0))
93 vn_log(NULL, "stuck in %s wait with iter at %d", reason, *iter);
94
95 const uint32_t shift = util_last_bit(*iter) - busy_wait_order - 1;
96 os_time_sleep(base_sleep_us << shift);
97 }
98