News for hackers. Stuff that matters.
Re:Basics of Futexes by nkurz on Friday July 13, 2018 @04:40PM (#17526513)
Does anyone know how "fair" the current Linux implementation of futexes is? I experimented with them soon after they were introduced, and at that time there was a great deal of favoritism: under heavy contention a thread/core that had just given up a lock was most likely to reclaim it, and other threads/cores would be starved. This isn't always a bad thing (and can sometimes even help performance) but didn't work well for my application.
Re:Basics of Futexes by ww520 on Friday July 13, 2018 @05:27PM (#17526849)
Most of the check to acquire the lock happens in user mode. It would favors the thread in RUNNING state that still has quantum left. For example, if a thread is running, has the lock, does its work, releases the lock (which wakes up other sleeping threads but they are in RUNNABLE state not RUNNING yet), and the running thread immediately loops back to acquire the lock again, it would succeed because the lock is free. When that running thread's quantum runs out and put to sleep (still holding the lock), the other awaken threads runs but the lock is not free so they promptly go back to sleep to wait for the lock. The old running thread wakes up and continues the cycle.

If you want fairer lock acquisition, you need to use locking priority. Just lower the running thread's priority when it finishes its work. The other sleeping threads with higher priority will have a chance to get the lock.

Re:Basics of Futexes by raattgift on Saturday July 14, 2018 @01:46AM (#17529020)
> Just lower the running thread's priority when it finishes its work. The other sleeping threads with higher priority will have a chance to get the lock.

What happens if immediately after the running thread lowers its priority priority it is descheduled? Is it still holding the lock at that point? Could it remain descheduled at low priority for a relatively long time while the other threads wake up and fail to acquire the lock (and also while any other unrelated threads go about their unlowered-priority business)?

Why wouldn't the workless thread just give up the lock (and possibly self-deschedule) when it has finished its work? If it is then assigned more work it would have to be scheduled and when running again contend for the lock, which is presumably what one wants, right?

Re:Basics of Futexes by ww520 on Saturday July 14, 2018 @12:25PM (#17530941)
You would release the lock first before lowering the priority.

As a separate issue, the priority inversion problem is addressed with the priority inheritance technique, which futex supports directly. Basically the priority of the thread holding the lock is boosted to the highest priority of all the threads sleeping at the lock, making sure it can run to completion. When the lock is released, the thread's priority is lowered back to its original level. All the xx_pi() APIs are the priority inheritance versions.

There are a number of ways to ensure fairness for lock acquisition; however, performance often suffers, so people just live with the problem and design the workload around it.