+ //Wait for semaphore which means signal queue is empty
+ pthread_pause_init(); //Make sure semaphore is init'd
+ sem_wait(&pthread_pause_sem);
+
+ //Only call this if you already acquired pthread_pause_sem semaphore!!!!
+ //Otherwise call pthread_pause_reschedule()
+
+ //Check if thread has running flag
+ int run = (pthread_user_data_internal(thread)->running);
+ //Check if privileged (single thread) mode is active
+ if(!pthread_equal(pthread_pause_holder, PTHREAD_XNULL) && !pthread_equal(pthread_pause_holder, thread)) {
+ run = 0;
+ }
+
+ //Send signal to initiate pause handler (keep trying while SigQueue is full)
+ //while(pthread_kill(thread, PTHREAD_XSIG_STOP) == EAGAIN) usleep(1000);
+ //printf("Sched %lu = %d (self: %lu, lck: %lu)\n", thread, run, pthread_self(), pthread_pause_holder);
+ while(pthread_sigqueue(thread, PTHREAD_XSIG_STOP,
+ (const union sigval){.sival_int=run}
+ ) == EAGAIN) usleep(1000);
+
+ //Wait for signal to be delivered
+ sem_wait(&pthread_pause_sem);
+ sem_post(&pthread_pause_sem);
+ pthread_user_data_unlock();
+
+ return 0;
+}
+
+int pthread_extra_yield() {
+ //Yield to both schedulers
+ pthread_pause_reschedule(pthread_self());
+ return pthread_yield();
+}
+
+///Sanity check to be sure there are no race conditions
+inline void pthread_pause_assert_owner() {
+ if(!pthread_equal(pthread_pause_holder,PTHREAD_XNULL))
+ assert(pthread_equal(pthread_pause_holder, pthread_self()));
+}
+
+///Pause specified thread (block until it is paused)