title: Lock that handles a high-contention, high-frequency situation
body: <p>I am looking for a lock implementation that degrades gracefully in the situation where you have two threads that constantly try to release and re-acquire the same lock, at a very high frequency.</p>
  
  <p>Of course it is clear that in this case the two threads won't significantly progress in parallel.  Theoretically, the best result would be achieved by running the whole thread 1, and then the whole thread 2, without any switching---because switching just creates massive overhead here.  So I am looking for a lock implementation that would handle this situation gracefully by keeping the same thread running for a while before switching, instead of constantly switching.</p>
  
  <h2>Long version of the question</h2>
  
  <p>As I would myself be tempted to answer this question by "your program is broken, don't do that", here is some justification about why we end up in this kind of situation.</p>
  
  <p>The lock is a "single global lock", i.e. a very coarse lock.  (It is the Global Interpreter Lock (GIL) inside PyPy, but the question is about how to do it in general, say if you have a C program.)</p>
  
  <p>We have the following situation:</p>
  
  <ul>
  <li><p>There is constantly contention.  That's expected in this case: the lock is a global lock that needs to be acquired for most threads to progress.  So we expect that a large fraction of them are waiting for the lock.  Only one of these threads can progress.</p></li>
  <li><p>The thread that holds the lock might do sometimes bursts of short releases.  A typical example would be if this thread does repeated calls to "something external", e.g. many short writes to a file.  Each of these writes is usually completed very quickly.  The lock still has to be released just in case this external thing turns out to take longer than expected (e.g. if the write actually needs to wait for disk I/O), so that another thread can acquire the lock in this case.</p></li>
  </ul>
  
  <p>If we use some standard mutex for the lock, then the lock will often switch to another thread as soon as the owner releases the lock.  But the problem is what if the program runs several threads that each wants to do a long burst of short releases.  The program ends up spending most of its time switching the lock between CPUs.</p>
  
  <p>It is much faster to run the same thread for a while before switching, at least as long as the lock is released for very short periods of time.  (E.g. on Linux/pthread a release immediately followed by an acquire will sometimes re-acquire the lock instantly even if there are other waiting threads; but we'd like this result in a large majority of cases, not just sometimes.)</p>
  
  <p>Of course, as soon as the lock is released for a longer period of time, then it becomes a good idea to transfer ownership of the lock to a different thread.</p>
  
  <p>So I'm looking for general ideas about how to do that.  I guess it should exist already somewhere---in a paper, or in some multithreading library?</p>
  
  <p>For reference, PyPy tries to implement something like this by polling: the lock is just a global variable, with synchronized compare-and-swap but no OS calls; one of the waiting threads is given the role of "stealer"; that "stealer" thread wakes up every 100 microseconds to check the variable.  This is not horribly bad (it costs maybe 1-2% of CPU time in addition to the 100% consumed by the running thread).  This actually implements what I'm asking for here, but the problem is that this is a hack that doesn't cleanly support more traditional cases of locks: for example, if thread 1 tries to send a message to thread 2 and wait for the answer, the two thread switches will take in average 100 microseconds each---which is far too much if the message is processed quickly.</p>