diff options
author | Vito Caputo <vcaputo@pengaru.com> | 2021-08-24 16:56:21 -0700 |
---|---|---|
committer | Vito Caputo <vcaputo@pengaru.com> | 2021-08-24 16:56:21 -0700 |
commit | b8ed34e910db12f58e9677af5c59891bba55707b (patch) | |
tree | b416323ae213a20816e3af94869c3d4e299a3d17 | |
parent | 61e02a7895b05debe5328439b3ef3f5cfdb438cb (diff) |
thunk: use __sync intrinsics for free lists
Enables using thunk.h in threaded programs
-rw-r--r-- | thunk.h | 34 |
1 files changed, 20 insertions, 14 deletions
@@ -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__); \ |