Mutex priority inversion

Ref: pthread_mutexattr_getprotocol(3p) - Linux manual page

I have a graphics program with threads running at various priorities. I want the rendering thread to be delayed as little as possible, and so I give it a higher priority than the other threads. There's some mutex contention between the threads for various data structures. What I want is 1) when a mutex is cleared and the high priority thread is waiting, the high priority thread is wakened immediately, even if all CPUs are busy, and 2) priority inversion protection (PTHREAD_PRIO_INHERIT), see link above.

Is that available in Rust?

1 Like

It sounds like you want a futex with priority inheritance. The standard library does not provide it.

I did a bit of searching and found this: linux_futex::PiFutex

1 Like

To add to this there is also crates.io: Rust Package Registry which implements lock_api on top of the crate you mentioned.

I haven't yet used either of these but I did a rough audit of them for the purpose of my dayjob, specifically evaluating if locks with priority inheritance were available with Rust.

The answer is yes, but with a big BUT. And that but is that the ecosystem doesn't use these. So as soon as you try to use anything that uses locking internally you are kind of screwed. For example, forget about using any of the standard channel libraries (unless they are explicitly fully lock free, which most (including std) aren't).

Your best bet is to look at no-std crates made for embedded, there people actually care about (and understand) hard real-time. (Just make sure you don't select something that uses spin locks.) When you are running real-time Linux with hard real-time workloads you are in the awkward middle spot.

1 Like

I know. I used to do robotics on QNX, an OS which takes priority very seriously and gets all this right.

Linux is more of "we'll get around to it at some point" scheduling.

Replying to myself to expand on my answer and leaving some links that may be relevant solutions to your code (or anyone who stumbles upon this in the future):

Consider various non-blocking algorithms and data structures.

  • Lock free means the whole system is guaranteed to make progress, but not any individual thread.
  • Wait free means that a thread won't ever have to wait.
  • Lock free and especially wait free algorithms are often slower (lower throughput) than their locking counterparts. If you don't need them, don't use them.

With those definitions and caveats out of the way, for my use cases I have been most interested in channels and channel like things. This is because the domain for my day job (control software industrial heavy vehicles and equipment) naturally fits into a mix between pub-sub bus and actors. But with the need for hard real-time for parts of the software. And various queues are the building blocks for this.

So here are some libraries I thought worth looking into for this, though I haven't audited them to make sure they are what they say:

Non-queues:

With respect to real time on Linux, you must use a real time kernel, as of writing that still requires a patch set, but any year now the last parts will be merged and it will mearly be a kernel compile time config option. No it won't be as good as a dedicated RTOS still. Also you need to use real time threads (SCHED_FIFO or higher) not normal nice-values.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.