Live data from Hacker News

Inside Rust's std and parking_lot mutexes – who wins?

blog.cuongle.dev

61–70 of 134 posts

Re: Inside Rust's std and parking_lot mutexes – who wins?

#61

Earlier quoted context omitted.

I'm very disappointed at this. The path of least resistance ought to be the right thing to do.

In the entire history of the standard library, we have never once seen a single report of anyone attempting to recover from poison.

Oh, I don't think recovery from poison is why poisoning is good. The reason poisoning is good is that at the moment you've acquired a lock on a mutex, you should be able to assume that the invariants guarded by the mutex are upheld (and panic if not).

Re: Inside Rust's std and parking_lot mutexes – who wins?

#62

> Poisoning: Panic Safety in Mutexes This is one of the biggest design flaws in Rust's std, in my opinion. Poisoning mutexes can have its use, but it's very rare in practice. Usually it's a huge misfeature that only introduces problems. More often than not panicking in a critical section is fine [1], but on the other hand poisoning a Mutex is a very convenient avenue for a denial-of-service attack, since a poisoned M…

> poisoning a Mutex is a very convenient avenue for a denial-of-service attack, since a poisoned Mutex will just completely brick a given critical section.

There's a tension between making DoS hard and avoiding RCE vulnerabilities, since the way to avoid an unplanned/bad code state becoming an RCE vulnerability is to crash as quickly and thoroughly as possible when you get into that state.

Re: Inside Rust's std and parking_lot mutexes – who wins?

#63

The C++ example given in the article is not correct. In C++ a mutex can wrap the object being protected.

I am not very familiar with C++'s API, but I believe that you are right that the C++ example in the article is incorrect, though for a different reason, namely that RAII is supported also in C++.

In C++, a class like std::lock_guard also provides "Automatic unlock". AFAICT, the article argues that only Rust's API provides that.

    {
        const std::lock_guard lock(mtx);
        account.balance -= amount;
        account.transaction_count++;
    } // Automatically unlocked.

Re: Inside Rust's std and parking_lot mutexes – who wins?

#64

Author of the original WTF::ParkingLot here (what rust’s parking_lot is based on). I’m surprised that this only compared to std on one platform (Linux). The main benefit of parking lot is that it makes locks very small, which then encourages the use of fine grained locking. For example, in JavaScriptCore (ParkingLot’s first customer), we stuff a 2-bit lock into every object header - so if there is ever a need to do s…

> The main benefit of parking lot is that it makes locks very small, which then encourages the use of fine grained locking. For example, in JavaScriptCore (ParkingLot’s first customer), we stuff a 2-bit lock into every object header - so if there is ever a need to do some locking for internal VM reasons on any object we can do that without increasing the size of the object IMHO that's a very cool feature which is ess…

Hypothetically Rust could make `Mutex` work with just two bits in the same way it makes `Option` the same size as `&T`. Annotate `InnerBlah` with the information about which bits are available and let `Mutex` use them.

Re: Inside Rust's std and parking_lot mutexes – who wins?

#65
post #64

Earlier quoted context omitted.

> The main benefit of parking lot is that it makes locks very small, which then encourages the use of fine grained locking. For example, in JavaScriptCore (ParkingLot’s first customer), we stuff a 2-bit lock into every object header - so if there is ever a need to do some locking for internal VM reasons on any object we can do that without increasing the size of the object IMHO that's a very cool feature which is ess…

Hypothetically Rust could make `Mutex ` work with just two bits in the same way it makes `Option ` the same size as `&T`. Annotate `InnerBlah` with the information about which bits are available and let `Mutex` use them.

References only have a single bit available as a niche (the null byte), which Option makes use of for null pointer optimization (https://doc.rust-lang.org/std/option/index.html#representati...).

In principle, you Rust could create something like std::num::NonZero and its corresponding sealed trait ZeroablePrimitive to mark that two bits are unused. But that doesn't exist yet as far as I know.

Re: Inside Rust's std and parking_lot mutexes – who wins?

#66

Earlier quoted context omitted.

Original post: https://webkit.org/blog/6161/locking-in-webkit/ Post that mentions the two bit lock: https://webkit.org/blog/7122/introducing-riptide-webkits-ret... I don’t know the details of the Rust port but I don’t imagine the part that involves the two bits to require unsafe, other than in the ways that any locking algorithm dances with unsafety in Rust (ownership relies on locking algorithms being correct)

This is very similar to how Java's object monitors are implemented. In OpenJDK, the markWord uses two bits to describe the state of an Object's monitor (see markWord.hpp:55). On contention, the monitor is said to become inflated , which basically means revving up a heavier lock and knowing how to find it. I'm a bit disappointed though, I assumed that you had a way of only using 2 bits of an object's memory somehow, b…

The lock takes two bits.

It’s just that if you use the WTF::Lock class the. You get a full byte simply because the smallest possible size of a class instance in C++ is one byte.

But there’s a template mixing thing you can use to get it to be two bits (you tell the mixin which byte to steal the two bits from and which two bits).

I suspend the same situation holds in the Rust port.

I am very familiar with how Java does locks. This is different. Look at the ParkingLot/parking_lot API. It lets you do much more than just locks, and there’s no direct equivalent of what Java VMs call the inflated or fat lock. The closest thing is the on demand created queue keyed by address.

Re: Inside Rust's std and parking_lot mutexes – who wins?

#67
post #9

Earlier quoted context omitted.

This article elaborates how it works.

Unhelpful response. This cuongle.dev article does not answer nextaccountic's question, and neither do the webkit.org articles that describe the parking lot concept but not this Rust implementation. The correct answer appears to be that it's impossible: `parking_lot::RawMutex` has private storage that owns the entire byte and does not provide any accessor for the unused six bits. https://docs.rs/parking_lot/0.12.5/par…

> and neither do the webkit.org articles that describe the parking lot concept but not this Rust implementation

The WebKit post explicitly talks about how you just need two bits to describe the lock state.

> The correct answer appears to be that it's impossible: `parking_lot::RawMutex` has private storage that owns the entire byte and does not provide any accessor for the unused six bits.

Not impossible. One way to do this is to just use parking_lot directly.

In WebKit there’s a template mixin that lets you steal two bits for locking however you like. JavaScriptCore uses this to steal two bits from the indexing type byte (if I remember right)

Re: Inside Rust's std and parking_lot mutexes – who wins?

#68
post #64

Earlier quoted context omitted.

> The main benefit of parking lot is that it makes locks very small, which then encourages the use of fine grained locking. For example, in JavaScriptCore (ParkingLot’s first customer), we stuff a 2-bit lock into every object header - so if there is ever a need to do some locking for internal VM reasons on any object we can do that without increasing the size of the object IMHO that's a very cool feature which is ess…

Hypothetically Rust could make `Mutex ` work with just two bits in the same way it makes `Option ` the same size as `&T`. Annotate `InnerBlah` with the information about which bits are available and let `Mutex` use them.

There was talk of Rust allowing stride != alignment. [1] I think this would mean if say `InnerBlah` has size 15 and alignment 8, `parking_lot::Mutex` can be size 16 rather than the current 24. Same would be true for an `OuterBlah` the mutex is one field of. But I don't think it'll happen.

[1] e.g. https://internals.rust-lang.org/t/pre-rfc-allow-array-stride...

Re: Inside Rust's std and parking_lot mutexes – who wins?

#69

Earlier quoted context omitted.

We're currently working on separating poison from mutexes, such that the default mutexes won't have poisoning (no more `.lock().unwrap()`), and if you want poisoning you can use something like `Mutex >`.

Yeah, I'm looking forward to it! While we're at it, another thing that'd be nice to get rid of is `AssertUnwindSafe`, which I find even more pointless.

Speaking only for myself (though several other people have expressed the same sentiment), I wish we could get rid of unwinding. That would be a massive challenge to do while preserving capabilities people care about, such as the ability to handle panics in http request handlers without exiting. I think it would be possible, though.

Re: Inside Rust's std and parking_lot mutexes – who wins?

#70
post #64

Earlier quoted context omitted.

Hypothetically Rust could make `Mutex ` work with just two bits in the same way it makes `Option ` the same size as `&T`. Annotate `InnerBlah` with the information about which bits are available and let `Mutex` use them.

References only have a single bit available as a niche (the null byte), which Option makes use of for null pointer optimization ( https://doc.rust-lang.org/std/option/index.html#representati... ). In principle, you Rust could create something like std::num::NonZero and its corresponding sealed trait ZeroablePrimitive to mark that two bits are unused. But that doesn't exist yet as far as I know.

There are also currently the unstable rustc_layout_scalar_valid_range_start and rustc_layout_scalar_valid_range_end attributes (which are used in the definition of NonNull, etc.) which could be used for some bit patterns.

Also aspirations to use pattern types for this sort of thing: https://github.com/rust-lang/rust/issues/135996

Post reply on HN