only initialize tls storage when tls_get is called for first time

This commit is contained in:
jacob 2024-04-04 18:47:19 -05:00
parent d29b0569ee
commit 2a2e857e08
3 changed files with 36 additions and 34 deletions

View File

@ -12,8 +12,8 @@
#define COBJMACROS #define COBJMACROS
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#include <initguid.h>
#include <Windows.h> #include <Windows.h>
#include <initguid.h>
#include <objbase.h> #include <objbase.h>
#include <uuids.h> #include <uuids.h>
#include <avrt.h> #include <avrt.h>

View File

@ -4,7 +4,7 @@
#include "scratch.h" #include "scratch.h"
#include "work.h" #include "work.h"
#define TLS_TABLE_RESERVE (GIGABYTE(1)) #define TLS_TABLE_RESERVE (MEGABYTE(1))
struct tls_info { struct tls_info {
u64 size; 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 tls_table_alloc(void)
{ {
struct tls_table t = { 0 }; struct tls_table t = { 0 };
t.arena = arena_alloc(TLS_TABLE_RESERVE); 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; return t;
} }
void tls_table_release(struct tls_table *t) void tls_table_release(struct tls_table *t)
{ {
/* Call release functions in reverse order */ /* Release allocated tls data in reverse order */
for (u64 i = (TLS_IDENTIFIER_COUNT - 1); i <= 0; --i) { for (u64 index_plus_one = t->allocation_order_count; index_plus_one > 0; --index_plus_one) {
tls_alloc_func *release = g_tls_info_table[i].release; enum tls_identifier identifier = t->allocation_order[index_plus_one - 1];
if (release) { void *data = t->lookup[identifier];
void *ptr = t->lookup[i]; struct tls_info *info = &g_tls_info_table[identifier];
release(ptr); if (info->release) {
info->release(data);
} }
} }
arena_release(&t->arena); 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;
}

View File

@ -31,14 +31,12 @@ enum tls_identifier {
struct tls_table { struct tls_table {
struct arena arena; struct arena arena;
void *lookup[TLS_IDENTIFIER_COUNT]; void *lookup[TLS_IDENTIFIER_COUNT];
enum tls_identifier allocation_order[TLS_IDENTIFIER_COUNT];
u64 allocation_order_count;
}; };
struct tls_table tls_table_alloc(void); struct tls_table tls_table_alloc(void);
void tls_table_release(struct tls_table *t); void tls_table_release(struct tls_table *t);
void *tls_get(enum tls_identifier identifier);
INLINE void *tls_get(enum tls_identifier identifier)
{
return sys_thread_get_tls()->lookup[identifier];
}
#endif #endif