summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2021-08-24 16:56:21 -0700
committerVito Caputo <vcaputo@pengaru.com>2021-08-24 16:56:21 -0700
commitb8ed34e910db12f58e9677af5c59891bba55707b (patch)
treeb416323ae213a20816e3af94869c3d4e299a3d17
parent61e02a7895b05debe5328439b3ef3f5cfdb438cb (diff)
thunk: use __sync intrinsics for free lists
Enables using thunk.h in threaded programs
-rw-r--r--thunk.h34
1 files changed, 20 insertions, 14 deletions
diff --git a/thunk.h b/thunk.h
index 4930f18..dc44055 100644
--- a/thunk.h
+++ b/thunk.h
@@ -475,20 +475,23 @@ struct thunk_t {
static void __thunk_free_##_name(thunk_t *thunk) { \
__thunk_environment_##_name *env = (__thunk_environment_##_name *)thunk;\
\
- env->next_free = __thunk_environment_cache_##_name; \
- __thunk_environment_cache_##_name = env; \
+ do { \
+ env->next_free = __thunk_environment_cache_##_name; \
+ } while (!__sync_bool_compare_and_swap(&__thunk_environment_cache_##_name, env->next_free, env));\
} \
\
static thunk_t * _THUNK_GEN_PROTO(__thunk_instantiate_##_name, __VA_ARGS__) {\
/* allocate and initialize environment, return it */ \
__thunk_environment_##_name *env; \
\
- if (__thunk_environment_cache_##_name) { \
- env = __thunk_environment_cache_##_name; \
- __thunk_environment_cache_##_name = env->next_free; \
- } else { \
- env = malloc(sizeof(*env)); \
+ while (env = __thunk_environment_cache_##_name) { \
+ if (__sync_bool_compare_and_swap(&__thunk_environment_cache_##_name, env, env->next_free))\
+ break; \
} \
+ \
+ if (!env) \
+ env = malloc(sizeof(*env)); \
+ \
assert(env); \
\
_THUNK_GEN_INITIALIZE(env, __VA_ARGS__); \
@@ -574,20 +577,23 @@ struct thunk_t {
void __thunk_free_##_name(thunk_t *thunk) { \
__thunk_environment_##_name *env = (__thunk_environment_##_name *)thunk;\
\
- env->next_free = __thunk_environment_cache_##_name; \
- __thunk_environment_cache_##_name = env; \
+ do { \
+ env->next_free = __thunk_environment_cache_##_name; \
+ } while (!__sync_bool_compare_and_swap(&__thunk_environment_cache_##_name, env->next_free, env));\
} \
\
thunk_t * _THUNK_GEN_PROTO(__thunk_instantiate_##_name, __VA_ARGS__) { \
/* allocate and populate environment, return it */ \
__thunk_environment_##_name *env; \
\
- if (__thunk_environment_cache_##_name) { \
- env = __thunk_environment_cache_##_name; \
- __thunk_environment_cache_##_name = env->next_free; \
- } else { \
- env = malloc(sizeof(*env)); \
+ while (env = __thunk_environment_cache_##_name) { \
+ if (__sync_bool_compare_and_swap(&__thunk_environment_cache_##_name, env, env->next_free))\
+ break; \
} \
+ \
+ if (!env) \
+ env = malloc(sizeof(*env)); \
+ \
assert(env); \
\
_THUNK_GEN_INITIALIZE(env, __VA_ARGS__); \
© All Rights Reserved