Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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
Replace RwLock by a futex based one on Linux #95801
Replace RwLock by a futex based one on Linux #95801
Changes from all commits
f1a4041
6cb463c
307aa58
7c28791
1f2c2bb
c4a4f48
8339381
File filter
Filter by extension
Conversations
Jump to
There are no files selected for viewing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems a bit strange to represent
WRITE_LOCKED
with a special reader count. I think using a separate bit forWRITE_LOCKED
would make the code more efficient (e.g. using native overflow flags to detect reader count overflow, usingfetch_or
for locking instead of a CAS loop, etc).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll try that out and see if it simplifies things. It probably does. Thanks. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried it, but it does not seem to simplify things.
fetch_or
doesn't seem very useful, because it should only set the bit if the lock isn't read-locked yet. If we unconditionally set the bit when attempting to lock, it will also be set when it's still read-locked and read-unlocking will need special handling for that situation.Simplifying the overflow check doesn't help, because at the points where this is checked, we also need to check the waiting bits too.
I also prefer to combine the fields, to make invalid states unrepresentable. (Effectively
enum { Unlocked, ReadLocked(NonZeroNonMaxU30), WriteLocked }
instead ofstruct { read_locked: u29, write_locked: bool }
.)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any reason why these are placed in the high bits rather than the low bits? In parking_lot I put the flags in the low bits so that counter overflows can be caught with
checked_add
which is slightly more efficient assembly code.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Putting them in the high bits makes it possible for the read condition to compile down to a single comparison:
readers(state) < MAX_READERS && !readers_waiting(state) && !writers_waiting(state)
is then equal to
(state as u32) < 0x3ffffffe
.(Not sure if llvm sees that though.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LLVM doesn't currently see this, although it sees a related pattern where the
0x3ffffffe
mask has only one set bit.Reported upstream: llvm/llvm-project#54856
(Note that I looked at
readers(state) < MAX_READERS & !readers_waiting(state) & !writers_waiting(state)
with bitwise and--LLVM has more trouble with logical and.)