only initialize tls storage when tls_get is called for first time
This commit is contained in:
parent
d29b0569ee
commit
2a2e857e08
@ -12,8 +12,8 @@
|
||||
|
||||
#define COBJMACROS
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <initguid.h>
|
||||
#include <Windows.h>
|
||||
#include <initguid.h>
|
||||
#include <objbase.h>
|
||||
#include <uuids.h>
|
||||
#include <avrt.h>
|
||||
|
||||
56
src/tls.c
56
src/tls.c
@ -4,7 +4,7 @@
|
||||
#include "scratch.h"
|
||||
#include "work.h"
|
||||
|
||||
#define TLS_TABLE_RESERVE (GIGABYTE(1))
|
||||
#define TLS_TABLE_RESERVE (MEGABYTE(1))
|
||||
|
||||
struct tls_info {
|
||||
u64 size;
|
||||
@ -22,39 +22,43 @@ GLOBAL READONLY struct tls_info g_tls_info_table[TLS_IDENTIFIER_COUNT] = {
|
||||
struct tls_table tls_table_alloc(void)
|
||||
{
|
||||
struct tls_table t = { 0 };
|
||||
|
||||
t.arena = arena_alloc(TLS_TABLE_RESERVE);
|
||||
|
||||
/* Build lookup table */
|
||||
for (u64 i = 0; i < TLS_IDENTIFIER_COUNT; ++i) {
|
||||
struct tls_info *info = &g_tls_info_table[i];
|
||||
arena_align(&t.arena, info->align);
|
||||
void *ptr = arena_push_array_zero(&t.arena, u8, info->size);
|
||||
t.lookup[i] = ptr;
|
||||
}
|
||||
|
||||
/* Call alloc functions */
|
||||
for (u64 i = 0; i < TLS_IDENTIFIER_COUNT; ++i) {
|
||||
tls_alloc_func *alloc = g_tls_info_table[i].alloc;
|
||||
if (alloc) {
|
||||
void *ptr = t.lookup[i];
|
||||
alloc(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
void tls_table_release(struct tls_table *t)
|
||||
{
|
||||
/* Call release functions in reverse order */
|
||||
for (u64 i = (TLS_IDENTIFIER_COUNT - 1); i <= 0; --i) {
|
||||
tls_alloc_func *release = g_tls_info_table[i].release;
|
||||
if (release) {
|
||||
void *ptr = t->lookup[i];
|
||||
release(ptr);
|
||||
/* Release allocated tls data in reverse order */
|
||||
for (u64 index_plus_one = t->allocation_order_count; index_plus_one > 0; --index_plus_one) {
|
||||
enum tls_identifier identifier = t->allocation_order[index_plus_one - 1];
|
||||
void *data = t->lookup[identifier];
|
||||
struct tls_info *info = &g_tls_info_table[identifier];
|
||||
if (info->release) {
|
||||
info->release(data);
|
||||
}
|
||||
}
|
||||
|
||||
arena_release(&t->arena);
|
||||
}
|
||||
|
||||
void *tls_get(enum tls_identifier identifier)
|
||||
{
|
||||
struct tls_table *t = sys_thread_get_tls();
|
||||
void **data_slot = &t->lookup[identifier];
|
||||
|
||||
if (!*data_slot) {
|
||||
/* Allocate */
|
||||
struct tls_info *info = &g_tls_info_table[identifier];
|
||||
arena_align(&t->arena, info->align);
|
||||
*data_slot = arena_push_array(&t->arena, u8, info->size);
|
||||
if (info->alloc) {
|
||||
info->alloc(*data_slot);
|
||||
} else {
|
||||
MEMZERO(*data_slot, info->size);
|
||||
}
|
||||
t->allocation_order[t->allocation_order_count] = identifier;
|
||||
++t->allocation_order_count;
|
||||
}
|
||||
|
||||
return *data_slot;
|
||||
}
|
||||
|
||||
12
src/tls.h
12
src/tls.h
@ -5,8 +5,8 @@
|
||||
/* TLS table (X macro) */
|
||||
/* ========================================================================== */
|
||||
|
||||
#define TLS_TABLE(X) \
|
||||
X(SCRATCH_TLS, struct scratch_tls, &scratch_tls_alloc, &scratch_tls_release) \
|
||||
#define TLS_TABLE(X) \
|
||||
X(SCRATCH_TLS, struct scratch_tls, &scratch_tls_alloc, &scratch_tls_release) \
|
||||
X(WORKER_TLS, struct worker_tls, NULL, NULL )
|
||||
|
||||
/* ========================================================================== */
|
||||
@ -31,14 +31,12 @@ enum tls_identifier {
|
||||
struct tls_table {
|
||||
struct arena arena;
|
||||
void *lookup[TLS_IDENTIFIER_COUNT];
|
||||
enum tls_identifier allocation_order[TLS_IDENTIFIER_COUNT];
|
||||
u64 allocation_order_count;
|
||||
};
|
||||
|
||||
struct tls_table tls_table_alloc(void);
|
||||
void tls_table_release(struct tls_table *t);
|
||||
|
||||
INLINE void *tls_get(enum tls_identifier identifier)
|
||||
{
|
||||
return sys_thread_get_tls()->lookup[identifier];
|
||||
}
|
||||
void *tls_get(enum tls_identifier identifier);
|
||||
|
||||
#endif
|
||||
|
||||
Loading…
Reference in New Issue
Block a user