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

Allow to configure RwLock max reads #3644

Merged
merged 6 commits into from
Apr 7, 2021

Conversation

zaharidichev
Copy link
Contributor

@zaharidichev zaharidichev commented Mar 25, 2021

Motivation

Currently RwLock MAX_READS is capped to 32 which is too low
for some usecases (see #3633).

Solution

This PR adds a constructor that allows for specifying the max reads.
It also bumps the default number of max reads from 32 to u32::MAX >> 3

Fix: #3633

@zaharidichev zaharidichev changed the title `allow to configure RwLock max reads Allow to configure RwLock max reads Mar 25, 2021
Signed-off-by: Zahari Dichev <zaharidichev@gmail.com>
Signed-off-by: Zahari Dichev <zaharidichev@gmail.com>
Comment on lines 13 to +23
#[cfg(not(loom))]
const MAX_READS: usize = 32;
const MAX_READS: u32 = std::u32::MAX >> 3;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The other PR set this to batch_semaphore::MAX_PERMITS. How much larger/smaller is this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well.. it is A LOT smaller than batch_semaphore::MAX_PERMITS. However, the idea is that we cannot acquire anything more than u32 from the semaphore so I think this is the right number. The shit mimics the one of batch_semaphore::MAX_PERMITS because on 32bit the last three bits are reserved for state. Does that sound correct?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean, the number here is half a billion, so it's probably large enough. However, we were having some trouble in the other PR after increasing it. It would be nice to run this on a 32-bit machine to see if that also happens with this one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the problems with the other PR were due to this test timing out. Will try and run it on 32bit to verify though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Darksonn I did run it on 32bit and it all seems fine. I think at the end the problem was at a faulty assert in the semaphore code.

Signed-off-by: Zahari Dichev <zaharidichev@gmail.com>
Signed-off-by: Zahari Dichev <zaharidichev@gmail.com>
{
assert!(
max_reads <= MAX_READS,
"a RwLock may not be created with more than MAX_READS ({})",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"a RwLock may not be created with more than MAX_READS ({})",
"a RwLock may not be created with more than {} readers",

Comment on lines +211 to +215
/// Creates a new instance of an `RwLock<T>` which is unlocked
/// and allows a maximum of `max_reads` concurrent readers.
///
/// # Examples
///
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should include a section on panics.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it worth making the MAX_READS const public just so we can link to it, or we can just mention the exact number in the docs ?

Copy link
Contributor

@Darksonn Darksonn Mar 29, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't make any of the other constants public. You can mention it as u32::MAX >> 3 or 2^29 - 1 as you prefer.

@Darksonn Darksonn added A-tokio Area: The main tokio crate M-sync Module: tokio/sync labels Mar 29, 2021
Signed-off-by: Zahari Dichev <zaharidichev@gmail.com>
@zaharidichev zaharidichev requested a review from Darksonn March 31, 2021 12:09
@davidpdrsn davidpdrsn linked an issue Apr 6, 2021 that may be closed by this pull request
@Darksonn Darksonn merged commit e89c898 into tokio-rs:master Apr 7, 2021
@Darksonn Darksonn mentioned this pull request Apr 12, 2021
@@ -271,6 +271,7 @@ impl Semaphore {
Self::MAX_PERMITS
);
let prev = self.permits.fetch_add(rem << Self::PERMIT_SHIFT, Release);
let prev = prev >> Self::PERMIT_SHIFT;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fix should probably be mentioned in the 1.5 changelog. I discovered this bug the hard way 😄
cc @Darksonn

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Can you open a PR to modify the changelog?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Opened here #3735

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-tokio Area: The main tokio crate M-sync Module: tokio/sync
Projects
None yet
Development

Successfully merging this pull request may close these issues.

RwLock blocks read access when there are many concurrent reads
3 participants