power_play/src/thread_local.h
2024-05-03 02:35:25 -05:00

66 lines
2.1 KiB
C

#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