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 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>
|
||||||
|
|||||||
56
src/tls.c
56
src/tls.c
@ -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;
|
||||||
|
}
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user