sem_timedwait.c raw

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