Skip to main content

Firefox

Improving Firefox responsiveness on macOS - Mozilla Hacks - the Web developer blogโ€‹

  • This improvement was achieved via a slight change in how locking is implemented within Firefox's memory allocator.
  • Putting a thread to sleep has significant performance implications and, thus, is not always the best option.
  • it might be advantageous to let a thread spin briefly if the lock it's trying to acquire is only held for a brief period.
  • It can result in higher performance and lower power consumption as spinning costs less than sleeping.
  • As you might have guessed by now, OSSpinLock offered excellent performance on a lightly loaded system but behaved poorly as the load ramped up.
  • This problem with OSSpinLock was known within Apple hence its deprecation
  • Enter os_unfair_lock, Apple's official replacement for OSSpinLock. If you still use OSSpinLock, you'll get explicit warnings to use it instead
  • So I used it, but the results were terrible. Performance in some of our automated tests degraded by as much as 30%.
  • 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
  • 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
  • The latter asks the kernel to use kernel-space adaptive spinning, and the former prevents it from spawning additional threads in the thread pools used by Apple's libraries
  • Did they work? Yes! Performance on lightly loaded systems was about the same as OSSpinLock, but on loaded ones, they provided massively better responsiveness
  • As an intermediate solution, I initially fell back to OSSpinLock on older systems. Later I managed to get rid of it for good by relying on os_unfair_lock plus manual spinning in user space