util: getting get_tracefile in u_trace.c to be thread safe

Remove the usage of DEBUG_GET_ONCE_FILE_OPTION because it's not a truly
once function, it's return a new FILE* object when calling to it when
the conditions are satisfied.

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/7151

Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
Acked-by: Marek Olšák <marek.olsak@amd.com>
Reviewed-by: Chia-I Wu <olvaffe@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18323>
This commit is contained in:
Yonggang Luo 2022-09-01 22:22:31 +08:00 committed by Marge Bot
parent 7dfd54cf4a
commit 5229a147c1

View file

@ -24,6 +24,7 @@
#include <inttypes.h>
#include "util/list.h"
#include "util/u_call_once.h"
#include "util/u_debug.h"
#include "util/u_inlines.h"
#include "util/u_fifo.h"
@ -40,6 +41,15 @@
int _u_trace_instrument;
struct u_trace_state {
util_once_flag once;
FILE *trace_file;
bool trace_format_json;
};
static struct u_trace_state u_trace_state = {
.once = UTIL_ONCE_FLAG_INIT
};
#ifdef HAVE_PERFETTO
int ut_perfetto_enabled;
@ -354,28 +364,41 @@ get_chunk(struct u_trace *ut, size_t payload_size)
DEBUG_GET_ONCE_BOOL_OPTION(trace_instrument, "GPU_TRACE_INSTRUMENT", false)
DEBUG_GET_ONCE_BOOL_OPTION(trace, "GPU_TRACE", false)
DEBUG_GET_ONCE_FILE_OPTION(trace_file, "GPU_TRACEFILE", NULL, "w")
DEBUG_GET_ONCE_OPTION(trace_file, "GPU_TRACEFILE", NULL)
DEBUG_GET_ONCE_OPTION(trace_format, "GPU_TRACE_FORMAT", "txt")
static FILE *
get_tracefile(void)
static void
trace_file_fini(void)
{
static FILE *tracefile = NULL;
static bool firsttime = true;
fclose(u_trace_state.trace_file);
u_trace_state.trace_file = NULL;
}
if (firsttime) {
tracefile = debug_get_option_trace_file();
if (!tracefile && debug_get_option_trace()) {
tracefile = stdout;
static void
u_trace_state_init_once(void)
{
const char *tracefile_name = debug_get_option_trace_file();
if (tracefile_name && !__check_suid()) {
u_trace_state.trace_file = fopen(tracefile_name, "w");
if (u_trace_state.trace_file != NULL) {
atexit(trace_file_fini);
}
if (tracefile || debug_get_option_trace_instrument())
p_atomic_inc(&_u_trace_instrument);
firsttime = false;
}
if (!u_trace_state.trace_file && debug_get_option_trace()) {
u_trace_state.trace_file = stdout;
}
return tracefile;
if (u_trace_state.trace_file || debug_get_option_trace_instrument())
p_atomic_inc(&_u_trace_instrument);
const char *trace_format = debug_get_option_trace_format();
u_trace_state.trace_format_json = !strcmp(trace_format, "json");
}
static void
u_trace_state_init(void)
{
util_call_once(&u_trace_state.once, u_trace_state_init_once);
}
static void
@ -402,6 +425,8 @@ u_trace_context_init(struct u_trace_context *utctx,
u_trace_read_ts read_timestamp,
u_trace_delete_flush_data delete_flush_data)
{
u_trace_state_init();
utctx->pctx = pctx;
utctx->create_timestamp_buffer = create_timestamp_buffer;
utctx->delete_timestamp_buffer = delete_timestamp_buffer;
@ -418,10 +443,9 @@ u_trace_context_init(struct u_trace_context *utctx,
list_inithead(&utctx->flushed_trace_chunks);
utctx->out = get_tracefile();
utctx->out = u_trace_state.trace_file;
const char *trace_format = debug_get_option_trace_format();
if (strcmp(trace_format, "json") == 0) {
if (u_trace_state.trace_format_json) {
utctx->out_printer = &json_printer;
} else {
utctx->out_printer = &txt_printer;