github.com/afumu/libc@v0.0.6/musl/src/thread/sem_timedwait.c (about)

     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  }