util: Add api util_call_once_with_context

This is used to remove the need of _MTX_INITIALIZER_NP in simple_mtx.h

Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
Reviewed-by: Jesse Natalie <jenatali@microsoft.com>
Reviewed-by: Jason Ekstrand <jason.ekstrand@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17122>
This commit is contained in:
Yonggang Luo
2022-06-18 23:55:49 +08:00
committed by Marge Bot
parent 201e1ba9db
commit 67cd0c44d2
3 changed files with 57 additions and 0 deletions

View File

@@ -118,6 +118,8 @@ files_mesa_util = files(
'timespec.h',
'u_atomic.c',
'u_atomic.h',
'u_call_once.c',
'u_call_once.h',
'u_debug_describe.c',
'u_debug_describe.h',
'u_debug_refcnt.c',

28
src/util/u_call_once.c Normal file
View File

@@ -0,0 +1,28 @@
/*
* Copyright 2022 Yonggang Luo
* SPDX-License-Identifier: MIT
*/
#include "u_call_once.h"
struct util_call_once_context_t
{
void *context;
util_call_once_callback_t callback;
};
static thread_local struct util_call_once_context_t call_once_context;
static void util_call_once_with_context_callback(void)
{
struct util_call_once_context_t *once_context = &call_once_context;
once_context->callback(once_context->context);
}
void util_call_once_with_context(once_flag *once, void *context, util_call_once_callback_t callback)
{
struct util_call_once_context_t *once_context = &call_once_context;
once_context->context = context;
once_context->callback = callback;
call_once(once, util_call_once_with_context_callback);
}

27
src/util/u_call_once.h Normal file
View File

@@ -0,0 +1,27 @@
/*
* Copyright 2022 Yonggang Luo
* SPDX-License-Identifier: MIT
*
* Extend C11 call_once to support context parameter
*/
#ifndef U_CALL_ONCE_H_
#define U_CALL_ONCE_H_
#include <stdbool.h>
#include "c11/threads.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef void (*util_call_once_callback_t)(void *context);
void util_call_once_with_context(once_flag *once, void *context, util_call_once_callback_t callback);
#ifdef __cplusplus
}
#endif
#endif /* U_CALL_ONCE_H_ */