pthread_exit(PTHREAD_CANCELED);
__pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME);
int __new_sem_wait(sem_t * sem){  volatile pthread_descr self = thread_self();  pthread_extricate_if extr;  int already_canceled = 0;  int spurious_wakeup_count;  /* Set up extrication interface */  extr.pu_object = sem;  extr.pu_extricate_func = new_sem_extricate_func;  __pthread_lock((struct _pthread_fastlock *) &sem->__sem_lock, self);  if (sem->__sem_value > 0) {    sem->__sem_value--;    __pthread_unlock((struct _pthread_fastlock *) &sem->__sem_lock);    return 0;  }  /* Register extrication interface */  THREAD_SETMEM(self, p_sem_avail, 0);  __pthread_set_own_extricate_if(self, &extr);  /* Enqueue only if not already cancelled. */  if (!(THREAD_GETMEM(self, p_canceled)      && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE))    enqueue(&sem->__sem_waiting, self);  else    already_canceled = 1;  __pthread_unlock((struct _pthread_fastlock *) &sem->__sem_lock);  if (already_canceled) {    __pthread_set_own_extricate_if(self, 0);    pthread_exit(PTHREAD_CANCELED);  }  /* Wait for sem_post or cancellation, or fall through if already canceled */  spurious_wakeup_count = 0;  while (1)    {      suspend(self);      if (THREAD_GETMEM(self, p_sem_avail) == 0	  && (THREAD_GETMEM(self, p_woken_by_cancel) == 0	      || THREAD_GETMEM(self, p_cancelstate) != PTHREAD_CANCEL_ENABLE))	{	  /* Count resumes that don't belong to us. */	  spurious_wakeup_count++;	  continue;	}      break;    }  __pthread_set_own_extricate_if(self, 0);  /* Terminate only if the wakeup came from cancellation. */  /* Otherwise ignore cancellation because we got the semaphore. */  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_exit(PTHREAD_CANCELED);  }  /* We got the semaphore */  return 0;}