Condvar and mutexes are for very different use cases though, and condvars are notoriously hard to get right, especially when supporting all the full set of posix behaviours with good performance.
You need a mutex to actually use condition variables. So, even if Rust's Condvar were just as bulky and complicated as the POSIX one offered by glibc, you saved on the associated mutex.
However from a quick glance Rust's Condvar is much smaller than pthread_cond_t
Condition variables per se don't seem that difficult. Mara did the Linux and Windows condition variables, both are pretty elegant. As with a graceful swan, there is lots happening out of sight (in the futex code Rust needs to cope with the fact that when people do futexes for $notLinux including OpenBSD and Fuchsia they inevitably put a spin on the idea, adding something they thought was cool or ignoring a hard problem they didn't fancy solving) but the general idea is very simple.
In contrast the glibc implementation is fiendishly complicated, but that's not because of POSIX, it's because they decided to do something fiendishly complicated, it hardly seems fair to demand that everybody who didn't need that complexity should respect how difficult it was anyway.
Example, glibc promises if six threads A, B, C, D, E, F wait on a condition variable in order and then it is signalled exactly four times, threads A, B, C and D are definitely woken and E, and F are definitely not woken. That's potentially useful for some purposes, but it's expensive, what if I don't care about this? Too bad, the price is baked in even though POSIX says nothing about this feature.
Rust doesn't care, so, if A, B, C, D, E, F wait on the CondVar and then it gets signalled exactly four times, well, four threads wake, but it could be any four. If A always waits again, signalling four times could just wake A four times, and each time it goes back to sleep. That seems useless, but if you wrote A, that's on you.
For what is worth, which threads are guaranteed to be unblocked is defined by the standard, at least under realtime scheduling.
I'm sure the rust devs got their condvar implementation exactly right at the first try, including cancellation, RT support, support for robust mutexes, wait morphing, process shared cond vars, etc.
For human programmers like the glibc ones, it took many decades, and there are very few that are confident enough to make large changes.
As I understand, there was no posix correct cond var for windows for many years untill after vista MS decided to expose the right primitives.
> For what is worth, which threads are guaranteed to be unblocked is defined by the standard, at least under realtime scheduling.
Where do you see this guarantee ?
> including cancellation, RT support, support for robust mutexes, wait morphing, process shared cond vars, etc
I'm sure doing the 100 metres sprint backwards, hopping on one leg while balancing a bowl of soup on your head would be trickier than the way Usain Bolt did it, but so what ?
What glibc tries to do is very complicated, yet when we see people using this feature they overwhelmingly don't require any of the complications, they just want a condition variable and that's all Rust's Condvar offers.
The posix spec is not the easiest to read, but pthread_cond_signal has wordings on the effect that the ordering of wakeups is unspecified except under realtime scheduling.
In any case glibc was blasted in the posix bug tracker for not respecting the wake up order even on non-RT and asking for the spec to be amended. Instead glibc had to rewrite its implementation to conform with the spec (and that fix introduced this bug).
> I'm sure doing the 100 metres sprint backwards, hopping on one leg while balancing a bowl of soup on your head would be trickier than the way Usain Bolt did it, but so what ?
you said that the complexity in glibc is not due to POSIX. All the items I mentioned (except for wait morphing) are required by POSIX/SUS. So what is it then?