From b8ed34e910db12f58e9677af5c59891bba55707b Mon Sep 17 00:00:00 2001 From: Vito Caputo Date: Tue, 24 Aug 2021 16:56:21 -0700 Subject: thunk: use __sync intrinsics for free lists Enables using thunk.h in threaded programs --- thunk.h | 34 ++++++++++++++++++++-------------- 1 file 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__); \ -- cgit v1.2.3