-
Notifications
You must be signed in to change notification settings - Fork 9
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
pthread_cond_timedwait error with EINVAL on macos #4
Comments
@dicej I tried to investigate further, but I don't have a clue. I changed the code to give a constant |
@skywhale Thanks so much for reporting this, and sorry for the delayed response. I'll take a look at this when I get a chance, probably this weekend. |
I've refactored the code a bit so it's using
Seems like it doesn't like either the condition or the mutex (or both). And it's a race condition, because sometimes it runs to completion without any error. Will continue studying it. |
I've also noticed that tests::aribitrary_case in the main test suite frequently deadlocks forever (with all threads waiting forever and never being notified). I'm guessing that's related even if the symptom is different. Here's my current theory: unlike on Linux, Android, and Windows, using the same interprocess mutex and/or condition variable from different memory mappings within the same process is not safe on MacOS (and maybe not on the BSDs in general). That's what the tests and benchmarks do: spawn separate threads for each receiver and sender as if they were other processes. I'm guessing there's something in the MacOS/BSD pthread implementation that assumes PTHREAD_PROCESS_SHARED mutexes and condition variables are not aliased in different memory locations within the same process, and although it usually works anyway, it doesn't always. When I change the code to make the senders and receiver all use the same memory mapping, everything seems to work reliably. That defeats the purpose of the tests, though, since there's no way that can happen when using separate processes. Next, I'm going to change tests to actually spawn separate processes instead of separate threads and see what happens. |
Update: I went ahead and modified the tests and benchmarks to fork processes instead of spawning threads. Unfortunately, that didn't address the issue -- I don't see any way forward from here, unfortunately. I'll update the README to indicate that MacOS is not currently supported until someone figures out how to fix this. |
This comment indicates that PTHREAD_PROCESS_SHARED has been broken in MacOS since Lion: bitcoin/bitcoin#19411 (comment). |
Thank you so much for looking into this @dicej. It's unfortunate that macOS Posix compliance is partial. I did a bit more research, and it seems pthread shared-process read/write lock has never been supported on macOS. Their pthread implementation seems to be based on BSD 7.4, which lacks the support of |
Hi, I went down the internet rabbit hole and searched about similar pthread errors and see if there are alternatives. Interestingly, boost has an However, digging a bit, it seems that on Mac, the implementation falls back to using a spin mutex.
so... perhaps the same thing should be done in |
Yes, I was wondering about some Mach-specific way to do locking, or else using named pipes just for locking (but still using the ring buffer for actually moving data around). The spin lock approach could also work. We'd either need to port the Boost code to Rust or create a Rust wrapper for a C++ library that exports the Boost functionality using a C API Rust can talk to. The latter would be easiest, I imagine. Ideally this would be its own crate so others could reuse it. Note that I don't expect I'll have time to work on this myself any time soon, but I'd be happy to review a PR. |
I'll see what I can do... no promises :-) |
This happens when I run
tests::bench_ipmpsc
.The error originates at
ipmpsc/src/lib.rs
Lines 160 to 164 in 2b4357e
A quick search suggests that
EINVAL
is returned when thetv_nsec
is invalid, but it doesn't seem to be the case. I added aprintln
right before the call, and I got:Note the error happens non-deterministically. Some iterations succeed. The error does not happen on a Ubuntu machine with the same version of rustc.
Environment:
OS: macOS Catalina 10.15.7 (19H15)
rustc: nightly-2020-12-09-x86_64-apple-darwin
The text was updated successfully, but these errors were encountered: