Archive for October 10, 2022

Monday, October 10, 2022

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 than OSSpinLock, 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 are OS_UNFAIR_LOCK_DATA_SYNCHRONIZATION and OS_UNFAIR_LOCK_ADAPTIVE_SPIN.

Jeff Johnson:

This only works because Firefox is not in the Mac App Store.


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.

Swift Was Always Going to Be Part of the OS

Jordan Rose:

Between Swift 1 and Swift 5 there was a massive amount of change, from shifting API design to changing ARC function conventions to adding missing optimizations to learning what was going to be practical and idiomatic in this new language. Looming over us the whole time was “ABI stability”, the point at which code using two different versions of Swift could interoperate. Why was this important, when so many other languages didn’t seem to bother? Because this was the very premise of Apple’s OS-based library distribution model: apps compiled for Swift 5 would work with an OS built on Swift 6; apps compiled with Swift 6 would still be able to “backwards-deploy” to an OS built on Swift 5. Without this, Apple couldn’t use Swift in its own public APIs.


We ended up (ab)using a feature called “rpath”, or “runtime search path”, which allowed an executable to find its dynamic libraries not by hardcoded path but by searching a series of directories. By making the search order start with /usr/lib/swift/ and following that with the app bundle, we could guarantee that apps would use the OS version of Swift if present and fall back to their embedded version otherwise.


This same technique was used just last year for Swift Concurrency, and then a serious bug was discovered in that first release…and it can’t be “fixed” in the backwards-deployment library because that wouldn’t help on the OSs that still contain libswiftConcurrency 1.0.


Specific functions can be marked with a not-yet-supported attribute to have them copied into clients instead of referenced by symbol name, much like a C static function defined in a header file. This only works for things like functions, methods, etc that don’t need identity, though; if the same implementation were used with a global stored variable, you’d end up with multiple copies of the global. And it also only works when the implementation is compatible with both past and future versions of the APIs it uses in turn.


In certain cases, the Swift team includes a “compatibility” library that’s linked in to the main app only (so that there’s exactly one) to bring some of the older OS’s support up to date.

Nick Lockwood:

I recall when ARC was added to Obj-C (and later fast enumeration, subscripting, object literals, etc) they had to bundle the ARCLite dylib with apps so they could run on earlier OSes that didn't support those features.


Midjourney Scam App

Ben Sandofsky:

There’s a scam app claiming to be Midjourney, and it’s charting in the App Store.


Not only did he file junk trademark claims for Midjourney, he just admitted he’s doing the same for Wordle.

Hugh Devaux:

Click on the link in his twitter bio and it goes straight to a stripe check out page for consultant work. That tells you everything you need to know.

Kudos on his page in using Next Computer Inc. Last time I checked it was still registered to @Apple


Weathergraph 1.0.123

Tomas Kafka:

Interactive daily forecast: Tap the day in the daily forecast to quickly scroll to its hourly forecast.

Plus: Redesigned sunrise & sunset section in the details, and more tweaks to the visuals of the chart.

I like being able to quickly jump to a given day. The main thing the app needs now is a way to switch locations.