sem_timedwait.c 685 B

123456789101112131415161718192021222324252627282930313233
  1. #include <semaphore.h>
  2. #include <limits.h>
  3. #include "pthread_impl.h"
  4. static void cleanup(void *p)
  5. {
  6. a_dec(p);
  7. }
  8. int sem_timedwait(sem_t *restrict sem, const struct timespec *restrict at)
  9. {
  10. pthread_testcancel();
  11. if (!sem_trywait(sem)) return 0;
  12. int spins = 100;
  13. while (spins-- && !(sem->__val[0] & SEM_VALUE_MAX) && !sem->__val[1])
  14. a_spin();
  15. while (sem_trywait(sem)) {
  16. int r, priv = sem->__val[2];
  17. a_inc(sem->__val+1);
  18. a_cas(sem->__val, 0, 0x80000000);
  19. pthread_cleanup_push(cleanup, (void *)(sem->__val+1));
  20. r = __timedwait_cp(sem->__val, 0x80000000, CLOCK_REALTIME, at, priv);
  21. pthread_cleanup_pop(1);
  22. if (r) {
  23. errno = r;
  24. return -1;
  25. }
  26. }
  27. return 0;
  28. }