const struct timespec * abstime)
struct timespec * reltime)
pthread_cond_timedwait_relative_old(pthread_cond_t *cond,				pthread_mutex_t *mutex,				const struct timespec * abstime){  volatile pthread_descr self = thread_self();  sigset_t unblock, initial_mask;  int retsleep, already_canceled, was_signalled;  sigjmp_buf jmpbuf;  pthread_extricate_if extr;  struct timeval now;  struct timespec reltime;requeue_and_wait_again:  /* Compute a time offset relative to now.  */  __gettimeofday (&now, NULL);  reltime.tv_nsec = abstime->tv_nsec - now.tv_usec * 1000;  reltime.tv_sec = abstime->tv_sec - now.tv_sec;  if (reltime.tv_nsec < 0) {    reltime.tv_nsec += 1000000000;    reltime.tv_sec -= 1;  }  if (reltime.tv_sec < 0)    return ETIMEDOUT;  retsleep = 0;  already_canceled = 0;  was_signalled = 0;  /* Set up extrication interface */  extr.pu_object = cond;  extr.pu_extricate_func = cond_extricate_func;  /* Register extrication interface */  __pthread_set_own_extricate_if(self, &extr);  /* Enqueue to wait on the condition and check for cancellation. */  __pthread_lock(&cond->__c_lock, self);  if (!(THREAD_GETMEM(self, p_canceled)      && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE))    enqueue(&cond->__c_waiting, self);  else    already_canceled = 1;  __pthread_unlock(&cond->__c_lock);  if (already_canceled) {    __pthread_set_own_extricate_if(self, 0);    pthread_exit(PTHREAD_CANCELED);  }  pthread_mutex_unlock(mutex);  if (atomic_decrement(&self->p_resume_count) == 0) {    /* Set up a longjmp handler for the restart signal, unblock       the signal and sleep. */    if (sigsetjmp(jmpbuf, 1) == 0) {      THREAD_SETMEM(self, p_signal_jmp, &jmpbuf);      THREAD_SETMEM(self, p_signal, 0);      /* Unblock the restart signal */      sigemptyset(&unblock);      sigaddset(&unblock, __pthread_sig_restart);      sigprocmask(SIG_UNBLOCK, &unblock, &initial_mask);      /* Sleep for the required duration */      retsleep = __libc_nanosleep(&reltime, NULL);      /* Block the restart signal again */      sigprocmask(SIG_SETMASK, &initial_mask, NULL);      was_signalled = 0;    } else {      retsleep = -1;      was_signalled = 1;    }    THREAD_SETMEM(self, p_signal_jmp, NULL);  }  /* Now was_signalled is true if we exited the above code     due to the delivery of a restart signal.  In that case,     we know we have been dequeued and resumed and that the     resume count is balanced.  Otherwise, there are some     cases to consider. First, try to bump up the resume count     back to zero. If it goes to 1, it means restart() was     invoked on this thread. The signal must be consumed     and the count bumped down and everything is cool.     Otherwise, no restart was delivered yet, so we remove     the thread from the queue. If this succeeds, it's a clear     case of timeout. If we fail to remove from the queue, then we     must wait for a restart. */  if (!was_signalled) {    if (atomic_increment(&self->p_resume_count) != -1) {      __pthread_wait_for_restart_signal(self);      atomic_decrement(&self->p_resume_count); /* should be zero now! */    } else {      int was_on_queue;      __pthread_lock(&cond->__c_lock, self);      was_on_queue = remove_from_queue(&cond->__c_waiting, self);      __pthread_unlock(&cond->__c_lock);      if (was_on_queue) {	__pthread_set_own_extricate_if(self, 0);	pthread_mutex_lock(mutex);	if (retsleep == 0)	  return ETIMEDOUT;	/* Woken by a signal: resume waiting as required by Single Unix	   Specification.  */	goto requeue_and_wait_again;      }      suspend(self);    }  }  __pthread_set_own_extricate_if(self, 0);  /* The remaining logic is the same as in other cancellable waits,     such as pthread_join sem_wait or pthread_cond wait. */  if (THREAD_GETMEM(self, p_woken_by_cancel)      && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE) {    THREAD_SETMEM(self, p_woken_by_cancel, 0);    pthread_mutex_lock(mutex);    pthread_exit(PTHREAD_CANCELED);  }  pthread_mutex_lock(mutex);  return 0;}