#ifdef AO_USE_ALMOST_LOCK_FREE /* Use the almost-non-blocking implementation regardless of the */ /* double-word CAS availability. */ #elif !defined(AO_HAVE_compare_double_and_swap_double) \
&& !defined(AO_HAVE_compare_double_and_swap) \
&& defined(AO_HAVE_compare_and_swap) # define AO_USE_ALMOST_LOCK_FREE #else /* If we have no compare-and-swap operation defined, we assume */ /* that we will actually be using CAS emulation. If we do that, */ /* it's cheaper to use the version-based implementation. */ # define AO_STACK_IS_LOCK_FREE #endif
#ifdef AO_USE_ALMOST_LOCK_FREE /* The number of low order pointer bits we can use for a small */ /* version number. */ # ifdefined(__LP64__) || defined(_LP64) || defined(_WIN64) # define AO_N_BITS 3 # else # define AO_N_BITS 2 # endif
/* The stack implementation knows only about the location of */ /* link fields in nodes, and nothing about the rest of the */ /* stack elements. Link fields hold an AO_t, which is not */ /* necessarily a real pointer. This converts the AO_t to a */ /* real (AO_t *) which is either NULL, or points at the link */ /* field in the next node. */ #define AO_REAL_NEXT_PTR(x) (AO_t *)((x) & ~AO_BIT_MASK)
/* The following two routines should not normally be used directly. */ /* We make them visible here for the rare cases in which it makes sense */ /* to share the AO_stack_aux between stacks. */ void
AO_stack_push_explicit_aux_release(volatile AO_t *list, AO_t *x,
AO_stack_aux *);
AO_INLINE void AO_stack_init(AO_stack_t *list)
{ # if AO_BL_SIZE == 2
list -> AO_aux.AO_stack_bl[0] = 0;
list -> AO_aux.AO_stack_bl[1] = 0; # else int i; for (i = 0; i < AO_BL_SIZE; ++i)
list -> AO_aux.AO_stack_bl[i] = 0; # endif
list -> AO_ptr = 0;
}
/* Convert an AO_stack_t to a pointer to the link field in */ /* the first element. */ #define AO_REAL_HEAD_PTR(x) AO_REAL_NEXT_PTR((x).AO_ptr)
#define AO_stack_push_release(l, e) \
AO_stack_push_explicit_aux_release(&((l)->AO_ptr), e, &((l)->AO_aux)) #define AO_HAVE_stack_push_release
# else/* Use fully non-blocking data structure, wide CAS */
#ifndef AO_HAVE_double_t /* Can happen if we're using CAS emulation, since we don't want to */ /* force that here, in case other atomic_ops clients don't want it. */ # ifdef __cplusplus
} /* extern "C" */ # endif # include "atomic_ops/sysdeps/standard_ao_double_t.h" # ifdef __cplusplus extern"C" { # endif #endif
typedefvolatile AO_double_t AO_stack_t; /* AO_val1 is version, AO_val2 is pointer. */ /* Note: AO_stack_t variables are not intended to be local ones, */ /* otherwise it is the client responsibility to ensure they have */ /* double-word alignment. */
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.