void __pthread_restart_new(pthread_descr th) { /* The barrier is proabably not needed, in which case it still documents our assumptions. The intent is to commit previous writes to shared memory so the woken thread will have a consistent view. Complementary read barriers are present to the suspend functions. */ WRITE_MEMORY_BARRIER(); kill(th->p_pid, __pthread_sig_restart); }
int sem_post(sem_t * sem) { pthread_descr self = thread_self(); pthread_descr th; #if 0 // AW11 struct pthread_request request; if (THREAD_GETMEM(self, p_in_sighandler) == NULL) #endif { __pthread_lock(&sem->__sem_lock, self); if (sem->__sem_waiting == NULL) { if (sem->__sem_value >= SEM_VALUE_MAX) { /* Overflow */ __set_errno(ERANGE); __pthread_unlock(&sem->__sem_lock); return -1; } sem->__sem_value++; __pthread_unlock(&sem->__sem_lock); } else { th = dequeue(&sem->__sem_waiting); __pthread_unlock(&sem->__sem_lock); th->p_sem_avail = 1; WRITE_MEMORY_BARRIER(); restart(th); } } #if 0 // AW11 else { /* If we're in signal handler, delegate post operation to the thread manager. */ if (__pthread_manager_request < 0) { if (__pthread_initialize_manager() < 0) { __set_errno(EAGAIN); return -1; } } request.req_kind = REQ_POST; request.req_args.post = sem; TEMP_FAILURE_RETRY(write_not_cancel(__pthread_manager_request, (char *) &request, sizeof(request))); } #endif return 0; }
int __pthread_once(pthread_once_t * once_control, void (*init_routine)(void)) { /* flag for doing the condition broadcast outside of mutex */ int state_changed; /* Test without locking first for speed */ if (*once_control == DONE) { READ_MEMORY_BARRIER(); return 0; } /* Lock and test again */ state_changed = 0; pthread_mutex_lock(&once_masterlock); /* If this object was left in an IN_PROGRESS state in a parent process (indicated by stale generation field), reset it to NEVER. */ if ((*once_control & 3) == IN_PROGRESS && (*once_control & ~3) != fork_generation) *once_control = NEVER; /* If init_routine is being called from another routine, wait until it completes. */ while ((*once_control & 3) == IN_PROGRESS) { pthread_cond_wait(&once_finished, &once_masterlock); } /* Here *once_control is stable and either NEVER or DONE. */ if (*once_control == NEVER) { *once_control = IN_PROGRESS | fork_generation; pthread_mutex_unlock(&once_masterlock); pthread_cleanup_push(pthread_once_cancelhandler, once_control); init_routine(); pthread_cleanup_pop(0); pthread_mutex_lock(&once_masterlock); WRITE_MEMORY_BARRIER(); *once_control = DONE; state_changed = 1; } pthread_mutex_unlock(&once_masterlock); if (state_changed) pthread_cond_broadcast(&once_finished); return 0; }