int gpr_stack_lockfree_pop(gpr_stack_lockfree *stack) { lockfree_node head; lockfree_node newhead; do { head.atm = gpr_atm_acq_load(&(stack->head.atm)); if (head.contents.index == INVALID_ENTRY_INDEX) { return -1; } newhead.atm = 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; }
void grpc_channel_update_call_size_estimate(grpc_channel *channel, size_t size) { size_t cur = (size_t)gpr_atm_no_barrier_load(&channel->call_size_estimate); if (cur < size) { /* size grew: update estimate */ gpr_atm_no_barrier_cas(&channel->call_size_estimate, (gpr_atm)cur, (gpr_atm)size); /* if we lose: never mind, something else will likely update soon enough */ } else if (cur == size) { /* no change: holding pattern */ } else if (cur > 0) { /* size shrank: decrease estimate */ gpr_atm_no_barrier_cas( &channel->call_size_estimate, (gpr_atm)cur, (gpr_atm)(GPR_MIN(cur - 1, (255 * cur + size) / 256))); /* if we lose: never mind, something else will likely update soon enough */ } }