Improving Firefox Responsiveness on macOS
Gabriele Svelto (tweet, Hacker News):
Performance in some of our automated tests degraded by as much as 30%.
os_unfair_lock
might be better behaved thanOSSpinLock
, but it sucked.As it turns out
os_unfair_lock
doesn’t spin on contention, it makes the calling thread sleep right away when it finds a contended lock.For the memory allocator this behavior was suboptimal and the performance regression unacceptable.
[…]
However, as I dug into Apple’s libraries and kernel, I noticed that some spin locks were indeed available, and they did the spinning in kernel-space where they could make a more informed choice with regards to load and scheduling. Those would have been an excellent choice for our use-case.
So how do you use them? Well, it turns out they’re not documented. They rely on a non-public function and flags which I had to duplicate in Firefox.
The function is
os_unfair_lock_with_options()
and the options I used areOS_UNFAIR_LOCK_DATA_SYNCHRONIZATION
andOS_UNFAIR_LOCK_ADAPTIVE_SPIN
.
This only works because Firefox is not in the Mac App Store.
Previously:
- Beware Spinlocks in User Space
- Locks, Thread Safety, and Swift: 2017 Edition
- os_unfair_lock
- OSSpinLock Is Unsafe
Update (2022-10-11): David Smith:
As a heads up, it is VERY easy to shoot yourself in the foot with the data synchronization flag there. It basically gets you something like Swift Concurrency pool behavior, but without the guardrails.
Update (2022-10-17): Oliver Hunt:
In case any one is interested, a few years ago on the @webkit blog, @filpizlo wrote quite a detailed post on how you could implement the high performance locks you might need when you’re replacing system libraries & so don’t use locks like typical apps[…]
There’s now a pull request to use os_unfair_lock_with_options()
in WebKit (via dpogue), however it seems to not improve on what WebKit is already doing.
1 Comment RSS · Twitter
heh, it looks like the WebKit devs saw the Mozilla post and decided to try it for themselves: https://github.com/WebKit/WebKit/pull/5266