int __pthread_mutex_unlock(pthread_mutex_t *m) { pthread_t self; int waiters = m->_m_waiters; int cont; int type = m->_m_type & 15; int priv = (m->_m_type & 128) ^ 128; if (type != PTHREAD_MUTEX_NORMAL) { self = __pthread_self(); if ((m->_m_lock&0x7fffffff) != self->tid) return EPERM; if ((type&3) == PTHREAD_MUTEX_RECURSIVE && m->_m_count) return m->_m_count--, 0; if (!priv) { self->robust_list.pending = &m->_m_next; __vm_lock(); } volatile void *prev = m->_m_prev; volatile void *next = m->_m_next; *(volatile void *volatile *)prev = next; if (next != &self->robust_list.head) *(volatile void *volatile *) ((char *)next - sizeof(void *)) = prev; } cont = a_swap(&m->_m_lock, (type & 8) ? 0x7fffffff : 0); if (type != PTHREAD_MUTEX_NORMAL && !priv) { self->robust_list.pending = 0; __vm_unlock(); } if (waiters || cont<0) __wake(&m->_m_lock, 1, priv); return 0; }
int __munmap(void *start, size_t len) { int ret; __vm_lock(-1); __vm_unlock(); ret = syscall(SYS_munmap, start, len); return ret; }
int pthread_barrier_destroy(pthread_barrier_t *b) { if (b->_b_limit < 0) { if (b->_b_lock) { int v; a_or(&b->_b_lock, INT_MIN); while ((v = b->_b_lock) & INT_MAX) __wait(&b->_b_lock, 0, v, 0); } __vm_lock(-1); __vm_unlock(); } return 0; }
static int pshared_barrier_wait(pthread_barrier_t *b) { int limit = (b->_b_limit & INT_MAX) + 1; int ret = 0; int v, w; if (limit==1) return PTHREAD_BARRIER_SERIAL_THREAD; while ((v=a_cas(&b->_b_lock, 0, limit))) __wait(&b->_b_lock, &b->_b_waiters, v, 0); /* Wait for <limit> threads to get to the barrier */ if (++b->_b_count == limit) { a_store(&b->_b_count, 0); ret = PTHREAD_BARRIER_SERIAL_THREAD; if (b->_b_waiters2) __wake(&b->_b_count, -1, 0); } else { a_store(&b->_b_lock, 0); if (b->_b_waiters) __wake(&b->_b_lock, 1, 0); while ((v=b->_b_count)>0) __wait(&b->_b_count, &b->_b_waiters2, v, 0); } __vm_lock(+1); /* Ensure all threads have a vm lock before proceeding */ if (a_fetch_add(&b->_b_count, -1)==1-limit) { a_store(&b->_b_count, 0); if (b->_b_waiters2) __wake(&b->_b_count, -1, 0); } else { while ((v=b->_b_count)) __wait(&b->_b_count, &b->_b_waiters2, v, 0); } /* Perform a recursive unlock suitable for self-sync'd destruction */ do { v = b->_b_lock; w = b->_b_waiters; } while (a_cas(&b->_b_lock, v, v==INT_MIN+1 ? 0 : v-1) != v); /* Wake a thread waiting to reuse or destroy the barrier */ if (v==INT_MIN+1 || (v==1 && w)) __wake(&b->_b_lock, 1, 0); __vm_unlock(); return ret; }