m-ou-se / rust-atomics-and-locks

Code examples, data structures, and links from my book, Rust Atomics and Locks.
Other
1.33k stars 120 forks source link

Error in read boundary check for RwLock 3 #35

Closed OliverFlecke closed 1 year ago

OliverFlecke commented 1 year ago

Type of error

Minor technical mistake

Location of the error

Line in code sample Section in book

Description of the error

In chapter 9 in the third version of the book's RwLock (avoiding write starvation), I believe the boundary assert check in the read guard for too many readers is slightly wrong.

The code is checking whether s is even, and afterwards asserts whether we have reached the maximum number of readers. As stated in the beginning of this section, just before the first code sample, u32::MAX is odd, which means u32::MAX - 2 will also be odd, and the assert statement will therefore never be true. I would argue the code should instead be s != u32::MAX - 3 to get the largest possible even number.

Using u32::MAX - 1 would also give an even number, but it would then be impossible to distinguish between the state of many readers and one waiting writer.

Relevant code sample:

pub fn read(&self) -> ReadGuard<T> {
    let mut s = self.state.load(Relaxed);
    loop {
        if s % 2 == 0 { // Even.
            assert!(s != u32::MAX - 2 /* should be 3 */, "too many readers");
            ...
}

Hope this helps!

Thank you for your excellent book! :heart:

m-ou-se commented 1 year ago

Thanks! Looks like I fixed that some time ago by using < rather than !=.