  Saturated locks often degrade the performance of a multithreaded application,
leading to a so-called scalability collapse problem. This problem arises when a
growing number of threads circulating through a saturated lock causes the
overall application performance to fade or even drop abruptly. This problem is
particularly (but not solely) acute on oversubscribed systems (systems with
more threads than available hardware cores). In this paper, we introduce GCR
(generic concurrency restriction), a mechanism that aims to avoid the
scalability collapse. GCR, designed as a generic, lock-agnostic wrapper,
intercepts lock acquisition calls, and decides when threads would be allowed to
proceed with the acquisition of the underlying lock. Furthermore, we present
GCR-NUMA, a non-uniform memory access (NUMA)-aware extension of GCR, that
strives to ensure that threads allowed to acquire the lock are those that run
on the same socket. The extensive evaluation that includes more than two dozen
locks, three machines and three benchmarks shows that GCR brings substantial
speedup (in many cases, up to three orders of magnitude) in case of contention
and growing thread counts, while introducing nearly negligible slowdown when
the underlying lock is not contended. GCR-NUMA brings even larger performance
gains starting at even lighter lock contention.
