diff --git a/src/runtime/future/future.c b/src/runtime/future/future.c index ec47ed684..1c1d1fa18 100644 --- a/src/runtime/future/future.c +++ b/src/runtime/future/future.c @@ -121,16 +121,16 @@ void yield(pony_actor_t* a) { suspend(r); } -inline volatile bool future_fulfilled(future_t *fut) { +inline bool future_fulfilled(future_t *fut) { return future_actor_get_fulfilled(fut); } -inline volatile void *future_read_value(future_t *fut) { +inline void *future_read_value(future_t *fut) { return future_actor_get_value(fut); } -volatile void *future_get(future_t *fut, pony_actor_t* actor) { - volatile void *result; +void *future_get(future_t *fut, pony_actor_t* actor) { + void *result; if (future_actor_get_value_and_fulfillment(fut, &result)) { return result; } @@ -138,7 +138,7 @@ volatile void *future_get(future_t *fut, pony_actor_t* actor) { return future_read_value(fut); } -void future_fulfil(future_t *f, volatile void *value) { +void future_fulfil(future_t *f, void *value) { future_actor_set_value(f, value); #ifdef DEBUG_PRINT fprintf(stderr, "[%p]\t%p <--- fulfil\n", (void *)pthread_self(), f); diff --git a/src/runtime/future/future.h b/src/runtime/future/future.h index ae594841a..273b31626 100644 --- a/src/runtime/future/future.h +++ b/src/runtime/future/future.h @@ -18,9 +18,9 @@ typedef enum { // ============================================================================= future_t *future_mk(); -volatile bool future_fulfilled(future_t *future); -volatile void *future_read_value(future_t *future); -void future_fulfil(future_t *future, volatile void *value); +bool future_fulfilled(future_t *future); +void *future_read_value(future_t *future); +void future_fulfil(future_t *future, void *value); // ============================================================================= // Actor-specific parts of the future library @@ -29,7 +29,7 @@ void future_fulfil(future_t *future, volatile void *value); void future_chain(future_t *future, pony_actor_t* actor_owning_closure, struct closure *closure); void future_await(future_t *future, pony_actor_t* actor_awaiting_future); void future_block(future_t *future, pony_actor_t* actor_blocking_on_future); -volatile void *future_get(future_t *future, pony_actor_t* actor_blocking_on_future); +void *future_get(future_t *future, pony_actor_t* actor_blocking_on_future); // ============================================================================= // Task-specific parts of the future library diff --git a/src/runtime/future/future_actor.c b/src/runtime/future/future_actor.c index 89deadc31..caca2f383 100644 --- a/src/runtime/future/future_actor.c +++ b/src/runtime/future/future_actor.c @@ -14,8 +14,8 @@ #define DEBUG_PRINT 1 typedef struct future_actor_fields { - volatile bool fulfilled; - volatile void *value; + bool fulfilled; + void *value; set_t *blocked; set_t *chained; set_t *awaiting; @@ -189,8 +189,7 @@ void future_actor_dispatch(pony_actor_t* this, void* p, uint64_t id, int argc, p } case FUT_MSG_FULFIL: { - // Discarding volatile here because it does not matter - volatile void *value; + void *value; bool fulfilled; fulfilled = future_actor_get_value_and_fulfillment(this, &value); @@ -227,24 +226,24 @@ future_actor_fields *get_fields(pony_actor_t *this) { return *(future_actor_fields **)this; } -void future_actor_set_value(pony_actor_t* this, volatile void *value) { +void future_actor_set_value(pony_actor_t* this, void *value) { future_actor_fields *state = get_fields(this); state->value = value; __sync_synchronize(); state->fulfilled = true; } -volatile bool future_actor_get_value_and_fulfillment(pony_actor_t* this, volatile void **value) { +bool future_actor_get_value_and_fulfillment(pony_actor_t* this, void **value) { future_actor_fields *state = get_fields(this); - volatile bool fulfilled = state->fulfilled; + bool fulfilled = state->fulfilled; __sync_synchronize(); *value = state->value; return fulfilled; } -volatile bool future_actor_get_fulfilled(pony_actor_t* this) { +bool future_actor_get_fulfilled(pony_actor_t* this) { future_actor_fields *state = get_fields(this); return state->fulfilled; } -volatile void *future_actor_get_value(pony_actor_t* this) { +void *future_actor_get_value(pony_actor_t* this) { future_actor_fields *state = get_fields(this); return state->value; } diff --git a/src/runtime/future/future_actor.h b/src/runtime/future/future_actor.h index ba99ed6db..bb71b36e0 100644 --- a/src/runtime/future/future_actor.h +++ b/src/runtime/future/future_actor.h @@ -16,9 +16,9 @@ enum pony_actor_t* future_create(); pony_msg_t* future_actor_message_type(uint64_t id); void future_actor_dispatch(pony_actor_t* this, void* p, uint64_t id, int argc, pony_arg_t* argv); -volatile bool future_actor_get_value_and_fulfillment(pony_actor_t* this, volatile void **value); -void future_actor_set_value(pony_actor_t* this, volatile void *value); -volatile bool future_actor_get_fulfilled(pony_actor_t* this); -volatile void *future_actor_get_value(pony_actor_t* this); +bool future_actor_get_value_and_fulfillment(pony_actor_t* this, void **value); +void future_actor_set_value(pony_actor_t* this, void *value); +bool future_actor_get_fulfilled(pony_actor_t* this); +void *future_actor_get_value(pony_actor_t* this); #endif diff --git a/src/runtime/future/tit_lazy.c b/src/runtime/future/tit_lazy.c index c96e34ec9..3ea36ee40 100644 --- a/src/runtime/future/tit_lazy.c +++ b/src/runtime/future/tit_lazy.c @@ -31,8 +31,8 @@ static pthread_once_t stack_pool_is_initialized = PTHREAD_ONCE_INIT; static mpmcq_t proper_stacks_for_reuse; static mpmcq_t side_stacks_for_reuse; static __thread lazy_tit_t *current; -static volatile unsigned int cached_side_stacks; -static unsigned int side_stack_cache_size; +static uint32_t cached_side_stacks; +static uint32_t side_stack_cache_size; static void trampoline_0(lazy_tit_t *new, fun_t_0 fun); // static void trampoline_1(lazy_tit_t *new, fun_t_1 fun, void *a); @@ -47,14 +47,15 @@ static inline void __end_trampoline(); void mk_stack(ucontext_t *fork) { if (side_stack_cache_size > 0) { - while (fork->uc_stack.ss_sp == NULL && cached_side_stacks > 0) { + while (fork->uc_stack.ss_sp == NULL && __atomic_load_n(&cached_side_stacks, __ATOMIC_CONSUME) > 0) { fork->uc_stack.ss_sp = mpmcq_pop(&side_stacks_for_reuse); } if (fork->uc_stack.ss_sp) { - int cache_size; + uint32_t cache_size; do { - cache_size = cached_side_stacks; - } while (!__sync_bool_compare_and_swap(&cached_side_stacks, cache_size, cache_size - 1)); + cache_size = __atomic_load_n(&cached_side_stacks, __ATOMIC_CONSUME); + } while (!__atomic_compare_exchange_n(&cached_side_stacks, &cache_size, cache_size - 1, false, __ATOMIC_RELEASE, __ATOMIC_RELAXED)); + // TODO: check the correctness and optimality of line above } } @@ -69,10 +70,11 @@ void mk_stack(ucontext_t *fork) { void return_allocated_stack_to_pool(void *stack_pointer) { bool free_stack = true; - int current_cache_size; + uint32_t current_cache_size; do { - current_cache_size = cached_side_stacks; - if (__sync_bool_compare_and_swap(&cached_side_stacks, current_cache_size, current_cache_size + 1)) { + current_cache_size = __atomic_load_n(&cached_side_stacks, __ATOMIC_CONSUME); + // TODO: check the correctness and optimality of line below + if (__atomic_compare_exchange_n(&cached_side_stacks, ¤t_cache_size, current_cache_size + 1, false, __ATOMIC_RELEASE, __ATOMIC_RELAXED)) { mpmcq_push(&side_stacks_for_reuse, stack_pointer); free_stack = false; break;