From 2a2e857e08768e70ce46a57c497e77d51c13af2e Mon Sep 17 00:00:00 2001 From: jacob Date: Thu, 4 Apr 2024 18:47:19 -0500 Subject: [PATCH] only initialize tls storage when tls_get is called for first time --- src/playback_wasapi.c | 2 +- src/tls.c | 56 +++++++++++++++++++++++-------------------- src/tls.h | 12 ++++------ 3 files changed, 36 insertions(+), 34 deletions(-) diff --git a/src/playback_wasapi.c b/src/playback_wasapi.c index b424b886..90efb163 100644 --- a/src/playback_wasapi.c +++ b/src/playback_wasapi.c @@ -12,8 +12,8 @@ #define COBJMACROS #define WIN32_LEAN_AND_MEAN -#include #include +#include #include #include #include diff --git a/src/tls.c b/src/tls.c index 62bc8fc3..ea46bc02 100644 --- a/src/tls.c +++ b/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; +} diff --git a/src/tls.h b/src/tls.h index b7bef0bc..a776d65b 100644 --- a/src/tls.h +++ b/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