summaryrefslogtreecommitdiff
path: root/thunk.h
diff options
context:
space:
mode:
Diffstat (limited to 'thunk.h')
-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