libGimbal
0.1.0
C17-Based Extended Standard Library and Cross-Language Runtime Framework
Loading...
Searching...
No Matches
gimbal_tls.h
Go to the documentation of this file.
1
/*! \file
2
* \brief Thread-local variable management
3
* \ingroup core
4
*
5
* This file provides a pair of macros serving as an abstraction layer
6
* between a platform's preferred thread-local storage mechanism, and
7
* the application.
8
*
9
* Where supported, GBL_TLS() will use real, compiler-enabled static
10
* TLS by simply declaring the variable with the "thread_local" keyword
11
* and proceeding to access it normally.
12
*
13
* If this preferred path is not available, using the same semantics, the
14
* back-end emulate this behavior by creating OS-level TLS storage using
15
* TinyCThread's C11 TLS API, which uses dynamically allocated storage
16
* and key-based lookups.
17
*
18
* \author 2023 Falco Girgis
19
* \copyright MIT License
20
*/
21
22
#
ifndef
GIMBAL_TLS_H
23
#
define
GIMBAL_TLS_H
24
25
#
include
<
tinycthread
.
h
>
26
#
include
"../preprocessor/gimbal_compiler.h"
27
28
#
if
defined
(
GBL_PSP
)
29
#
define
GBL_TLS_EMULATED
1
30
#
endif
31
32
/*! \def GBL_TLS(type, name, init)
33
*
34
* Defines a thread-local variable using the given information,
35
* and either using compiler or OS-level TLS depending on the
36
* platform.
37
*
38
* \param type variable type
39
* \param name variable name
40
* \param init variable initializer
41
*
42
* \sa GBL_TLS_LOAD()
43
*/
44
#
if
!
GBL_TLS_EMULATED
45
#
define
GBL_TLS
(
type
,
name
,
...
)
GBL_THREAD_LOCAL
type
name
=
__VA_ARGS__
46
#
else
47
#
define
GBL_TLS
(
type
,
name
,
...
)
48
tss_t
name
;
49
static
void
tls_
##
name
##
_init_
(
void
)
{
50
int
res
=
tss_create
(
&
name
,
free
)
;
51
GBL_ASSERT
(
res
==
thrd_success
,
52
"Failed to create "
#
type
" TLS for "
#
name
)
;
53
}
54
static
type
*
tls_
##
name
##
_load_
(
void
)
{
55
static
once_flag
once
=
ONCE_FLAG_INIT
;
56
call_once
(
&
once
,
tls_
##
name
##
_init_
)
;
57
type
*
pPtr
=
tss_get
(
name
)
;
58
if
(
!
pPtr
)
{
59
pPtr
=
malloc
(
sizeof
(
type
)
)
;
60
type
temp
=
__VA_ARGS__
;
61
memcpy
(
pPtr
,
&
temp
,
sizeof
(
type
)
)
;
62
const
int
res
=
tss_set
(
name
,
pPtr
)
;
63
GBL_ASSERT
(
res
==
thrd_success
,
64
"Failed to set "
#
type
" TLS for "
#
name
)
;
65
}
66
return
pPtr
;
67
}
68
#
endif
69
70
/*! \def GBL_TLS_LOAD(name)
71
*
72
* Fetches a pointer to a thread-local variable that was
73
* previously declared with GBL_TLS()
74
*
75
* \param name variable name
76
* \return pointer address of the given TLS variable
77
*
78
* \sa GBL_TLS()
79
*/
80
#
if
!
GBL_TLS_EMULATED
81
#
define
GBL_TLS_LOAD
(
name
)
&
name
82
#
else
83
#
define
GBL_TLS_LOAD
(
name
)
tls_
##
name
##
_load_
(
)
84
#
endif
85
86
#
endif
// GIMBAL_TLS_H
GBL_THREAD_LOCAL
#define GBL_THREAD_LOCAL
Definition
gimbal_compiler.h:248
lib
api
gimbal
core
gimbal_tls.h
Generated by
1.13.2