]>
Commit | Line | Data |
---|---|---|
320054e8 DG |
1 | #include "pthread_impl.h" |
2 | ||
3 | int __pthread_mutex_unlock(pthread_mutex_t *m) | |
4 | { | |
5 | pthread_t self; | |
6 | int waiters = m->_m_waiters; | |
7 | int cont; | |
8 | int type = m->_m_type & 15; | |
9 | int priv = (m->_m_type & 128) ^ 128; | |
f41256b6 DG |
10 | int new = 0; |
11 | int old; | |
320054e8 DG |
12 | |
13 | if (type != PTHREAD_MUTEX_NORMAL) { | |
14 | self = __pthread_self(); | |
f41256b6 DG |
15 | old = m->_m_lock; |
16 | int own = old & 0x3fffffff; | |
17 | if (own != self->tid) | |
320054e8 DG |
18 | return EPERM; |
19 | if ((type&3) == PTHREAD_MUTEX_RECURSIVE && m->_m_count) | |
20 | return m->_m_count--, 0; | |
f41256b6 DG |
21 | if ((type&4) && (old&0x40000000)) |
22 | new = 0x7fffffff; | |
320054e8 DG |
23 | if (!priv) { |
24 | self->robust_list.pending = &m->_m_next; | |
33c3753c | 25 | #ifdef __wasilibc_unmodified_upstream |
320054e8 | 26 | __vm_lock(); |
33c3753c | 27 | #endif |
320054e8 DG |
28 | } |
29 | volatile void *prev = m->_m_prev; | |
30 | volatile void *next = m->_m_next; | |
31 | *(volatile void *volatile *)prev = next; | |
32 | if (next != &self->robust_list.head) *(volatile void *volatile *) | |
33 | ((char *)next - sizeof(void *)) = prev; | |
34 | } | |
33c3753c | 35 | #ifdef __wasilibc_unmodified_upstream |
f41256b6 DG |
36 | if (type&8) { |
37 | if (old<0 || a_cas(&m->_m_lock, old, new)!=old) { | |
38 | if (new) a_store(&m->_m_waiters, -1); | |
39 | __syscall(SYS_futex, &m->_m_lock, FUTEX_UNLOCK_PI|priv); | |
40 | } | |
41 | cont = 0; | |
42 | waiters = 0; | |
43 | } else { | |
44 | cont = a_swap(&m->_m_lock, new); | |
45 | } | |
33c3753c AB |
46 | #else |
47 | cont = a_swap(&m->_m_lock, new); | |
48 | #endif | |
320054e8 DG |
49 | if (type != PTHREAD_MUTEX_NORMAL && !priv) { |
50 | self->robust_list.pending = 0; | |
33c3753c | 51 | #ifdef __wasilibc_unmodified_upstream |
320054e8 | 52 | __vm_unlock(); |
33c3753c | 53 | #endif |
320054e8 DG |
54 | } |
55 | if (waiters || cont<0) | |
56 | __wake(&m->_m_lock, 1, priv); | |
57 | return 0; | |
58 | } | |
59 | ||
60 | weak_alias(__pthread_mutex_unlock, pthread_mutex_unlock); |