Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WT-3127 bug: CPU yield calls don't necessarily imply memory barriers #3244

Merged
merged 1 commit into from
Jan 17, 2017

Conversation

keithbostic
Copy link
Contributor

bug: CPU yield calls don't necessarily imply memory barriers
Add a full-barrier as part of the yield call.

Add a full-barrier as part of the yield call.
@keithbostic keithbostic self-assigned this Jan 12, 2017
@agorrod
Copy link
Member

agorrod commented Jan 13, 2017

@keithbostic which uses of our yield function assume that it acts as a barrier? I don't mind the change, but I'd like to understand the motivation for making it.

@keithbostic
Copy link
Contributor Author

@agorrod

which uses of our yield function assume that it acts as a barrier?

We have loops like this one from __log_slot_close:

/*
 * A thread setting the unbuffered flag sets the unbuffered size after
 * setting the flag.  There could be a delay between a thread setting
 * the flag, a thread closing the slot, and the original thread setting
 * that value.  If the state is unbuffered, wait for the unbuffered
 * size to be set.
 */
while (WT_LOG_SLOT_UNBUFFERED_ISSET(old_state) &&
    slot->slot_unbuffered == 0)
        __wt_yield();

Technically, I don't think there's anything that prevents caching slot->slot_unbuffered in a register instead of re-reading it from memory in each iteration.

@agorrod
Copy link
Member

agorrod commented Jan 16, 2017

I don't think there's anything that prevents caching slot->slot_unbuffered in a register instead of re-reading it from memory in each iteration

Does a barrier in a function call change that? I thought the way to ensure the compiler doesn't cache a local copy was to mark the field volatile?

I like this change - I'm just trying to make sure I understand..

@keithbostic
Copy link
Contributor Author

Does a barrier in a function call change that? I thought the way to ensure the compiler doesn't cache a local copy was to mark the field volatile?

Yes, the compiler can't cache a value across a memory barrier. Declaring volatile would have the same effect with respect to variable caching, but would require all callers of __wt_yield to add volatile declarations, so this is a simpler change. (To be fair, a barrier is a blunter change as no values can be cached across the call, whereas only a single value must be discarded with volatile. Since we're yielding the CPU, I don't think it matters here.)

I don't like using volatile much (here's the Linux kernel commentary, which covers the discussion pretty well), but there are smarter people than me who strongly disagree. :)

@agorrod
Copy link
Member

agorrod commented Jan 17, 2017

Thanks for the explanations @keithbostic lgtm

@agorrod agorrod merged commit 0492377 into develop Jan 17, 2017
@agorrod agorrod deleted the wt-3127-add-barrier-to-yield branch January 17, 2017 01:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants