#include "pthread_impl.h" #include "__lock.h" weak_alias(__lock_fast, __lock); weak_alias(__unlock_fast, __unlock); void __lock_slow(volatile int *l, int current) { /* A first spin lock acquisition loop, for the case of medium congestion. */ for (unsigned i = 0; i < 10; ++i) { if (current < 0) current -= INT_MIN + 1; // assertion: current >= 0 int val = a_cas(l, current, INT_MIN + (current + 1)); if (val == current) return; current = val; } // Spinning failed, so mark ourselves as being inside the CS. current = a_fetch_add(l, 1) + 1; /* The main lock acquisition loop for heavy congestion. The only change to the value performed inside that loop is a successful lock via the CAS that acquires the lock. */ for (;;) { /* We can only go into wait, if we know that somebody holds the lock and will eventually wake us up, again. */ if (current < 0) { __futexwait(l, current, 1); current -= INT_MIN + 1; } /* assertion: current > 0, because the count includes us already. */ int val = a_cas(l, current, INT_MIN + current); if (val == current) return; current = val; } }