#ifndef THREAD_LOCAL #define THREAD_LOCAL /* ========================== * * Thread local store * ========================== */ struct thread_local_store { void **lookup; struct arena arena; u64 allocation_order_count; u64 *allocation_order; }; struct thread_local_store thread_local_store_alloc(void); void thread_local_store_release(struct thread_local_store *t); /* ========================== * * Thread local var * ========================== */ #define THREAD_LOCAL_VAR_ALLOC_FUNC_DEF(name, arg_name) void name(void *arg_name) typedef THREAD_LOCAL_VAR_ALLOC_FUNC_DEF(thread_local_var_alloc_func, ptr); #define THREAD_LOCAL_VAR_RELEASE_FUNC_DEF(name, arg_name) void name(void *arg_name) typedef THREAD_LOCAL_VAR_RELEASE_FUNC_DEF(thread_local_var_release_func, ptr); struct thread_local_var_meta { struct atomic_u64 id_plus_one; u64 size; u64 align; thread_local_var_alloc_func *alloc; thread_local_var_release_func *release; }; #define THREAD_LOCAL_VAR_DEF(var_name, type, alloc_func, release_func) \ struct { struct thread_local_var_meta meta; type *_t; } var_name = { \ .meta = { \ .size = sizeof(type), \ .align = alignof(type), \ .alloc = (alloc_func), \ .release = (release_func) \ } \ } #define THREAD_LOCAL_VAR_DECL_EXTERN(var_name, type) struct __thread_local_struct##var_name { struct thread_local_var_meta meta; type *_t; }; extern struct __thread_local_struct##var_name var_name; #define THREAD_LOCAL_VAR_DEF_EXTERN(var_name, type, alloc_func, release_func) \ struct __thread_local_struct##var_name var_name = { \ .meta = { \ .size = sizeof(type), \ .align = alignof(type), \ .alloc = (alloc_func), \ .release = (release_func) \ } \ } #if TYPEOF_DEFINED # define thread_local_var_eval(var_ptr) (typeof((var_ptr)->_t))(_thread_local_var_eval(&(var_ptr)->meta)); #else # define thread_local_var_eval(var_ptr) (void *)(_thread_local_var_eval(&(var_ptr)->meta)); #endif void *_thread_local_var_eval(struct thread_local_var_meta *meta); #endif