pthread_mutex_timedlock.c 836 B

1234567891011121314151617181920212223242526272829303132
  1. #include "pthread_impl.h"
  2. int pthread_mutex_timedlock(pthread_mutex_t *restrict m, const struct timespec *restrict at)
  3. {
  4. if ((m->_m_type&15) == PTHREAD_MUTEX_NORMAL
  5. && !a_cas(&m->_m_lock, 0, EBUSY))
  6. return 0;
  7. int r, t, priv = (m->_m_type & 128) ^ 128;
  8. r = pthread_mutex_trylock(m);
  9. if (r != EBUSY) return r;
  10. int spins = 100;
  11. while (spins-- && m->_m_lock) a_spin();
  12. while ((r=pthread_mutex_trylock(m)) == EBUSY) {
  13. if (!(r=m->_m_lock) || ((r&0x40000000) && (m->_m_type&4)))
  14. continue;
  15. if ((m->_m_type&3) == PTHREAD_MUTEX_ERRORCHECK
  16. && (r&0x7fffffff) == __pthread_self()->tid)
  17. return EDEADLK;
  18. a_inc(&m->_m_waiters);
  19. t = r | 0x80000000;
  20. a_cas(&m->_m_lock, r, t);
  21. r = __timedwait(&m->_m_lock, t, CLOCK_REALTIME, at, 0, 0, priv);
  22. a_dec(&m->_m_waiters);
  23. if (r && r != EINTR) break;
  24. }
  25. return r;
  26. }