|
|
|
@ -72,11 +72,6 @@ typedef union lockfree_node { |
|
|
|
|
struct gpr_stack_lockfree { |
|
|
|
|
lockfree_node *entries; |
|
|
|
|
lockfree_node head; /* An atomic entry describing curr head */ |
|
|
|
|
|
|
|
|
|
#ifndef NDEBUG |
|
|
|
|
/* Bitmap of pushed entries to check for double-push or pop */ |
|
|
|
|
gpr_atm pushed[(INVALID_ENTRY_INDEX + 1) / (8 * sizeof(gpr_atm))]; |
|
|
|
|
#endif |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
gpr_stack_lockfree *gpr_stack_lockfree_create(size_t entries) { |
|
|
|
@ -91,9 +86,6 @@ gpr_stack_lockfree *gpr_stack_lockfree_create(size_t entries) { |
|
|
|
|
/* Clear out all entries */ |
|
|
|
|
memset(stack->entries, 0, entries * sizeof(stack->entries[0])); |
|
|
|
|
memset(&stack->head, 0, sizeof(stack->head)); |
|
|
|
|
#ifndef NDEBUG |
|
|
|
|
memset(&stack->pushed, 0, sizeof(stack->pushed)); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
GPR_ASSERT(sizeof(stack->entries->atm) == sizeof(stack->entries->contents)); |
|
|
|
|
|
|
|
|
@ -130,19 +122,6 @@ int gpr_stack_lockfree_push(gpr_stack_lockfree *stack, int entry) { |
|
|
|
|
newhead.contents.aba_ctr = ++curent.contents.aba_ctr; |
|
|
|
|
gpr_atm_no_barrier_store(&stack->entries[entry].atm, curent.atm); |
|
|
|
|
|
|
|
|
|
#ifndef NDEBUG |
|
|
|
|
/* Check for double push */ |
|
|
|
|
{ |
|
|
|
|
int pushed_index = entry / (int)(8 * sizeof(gpr_atm)); |
|
|
|
|
int pushed_bit = entry % (int)(8 * sizeof(gpr_atm)); |
|
|
|
|
gpr_atm old_val; |
|
|
|
|
|
|
|
|
|
old_val = gpr_atm_no_barrier_fetch_add(&stack->pushed[pushed_index], |
|
|
|
|
((gpr_atm)1 << pushed_bit)); |
|
|
|
|
GPR_ASSERT((old_val & (((gpr_atm)1) << pushed_bit)) == 0); |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
do { |
|
|
|
|
/* Atomically get the existing head value for use */ |
|
|
|
|
head.atm = gpr_atm_no_barrier_load(&(stack->head.atm)); |
|
|
|
@ -168,18 +147,6 @@ int gpr_stack_lockfree_pop(gpr_stack_lockfree *stack) { |
|
|
|
|
gpr_atm_no_barrier_load(&(stack->entries[head.contents.index].atm)); |
|
|
|
|
|
|
|
|
|
} while (!gpr_atm_no_barrier_cas(&(stack->head.atm), head.atm, newhead.atm)); |
|
|
|
|
#ifndef NDEBUG |
|
|
|
|
/* Check for valid pop */ |
|
|
|
|
{ |
|
|
|
|
int pushed_index = head.contents.index / (8 * sizeof(gpr_atm)); |
|
|
|
|
int pushed_bit = head.contents.index % (8 * sizeof(gpr_atm)); |
|
|
|
|
gpr_atm old_val; |
|
|
|
|
|
|
|
|
|
old_val = gpr_atm_no_barrier_fetch_add(&stack->pushed[pushed_index], |
|
|
|
|
-((gpr_atm)1 << pushed_bit)); |
|
|
|
|
GPR_ASSERT((old_val & (((gpr_atm)1) << pushed_bit)) != 0); |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
return head.contents.index; |
|
|
|
|
} |
|
|
|
|