1 #include "pthread_impl.h"
8 static void unwait(pthread_cond_t
*c
, pthread_mutex_t
*m
)
10 /* Removing a waiter is non-trivial if we could be using requeue
11 * based broadcast signals, due to mutex access issues, etc. */
13 if (c
->_c_mutex
== (void *)-1) {
14 a_dec(&c
->_c_waiters
);
15 if (c
->_c_destroy
) __wake(&c
->_c_waiters
, 1, 0);
19 while (a_swap(&c
->_c_lock
, 1))
20 __wait(&c
->_c_lock
, &c
->_c_lockwait
, 1, 1);
22 if (c
->_c_waiters2
) c
->_c_waiters2
--;
23 else a_dec(&m
->_m_waiters
);
25 a_store(&c
->_c_lock
, 0);
26 if (c
->_c_lockwait
) __wake(&c
->_c_lock
, 1, 1);
28 a_dec(&c
->_c_waiters
);
29 if (c
->_c_destroy
) __wake(&c
->_c_waiters
, 1, 1);
32 static void cleanup(void *p
)
36 pthread_mutex_lock(cm
->m
);
39 int pthread_cond_timedwait(pthread_cond_t
*restrict c
, pthread_mutex_t
*restrict m
, const struct timespec
*restrict ts
)
41 struct cm cm
= { .c
=c
, .m
=m
};
44 if (m
->_m_type
&& (m
->_m_lock
&INT_MAX
) != pthread_self()->tid
)
47 if (ts
&& ts
->tv_nsec
>= 1000000000UL)
52 a_inc(&c
->_c_waiters
);
54 if (c
->_c_mutex
!= (void *)-1) {
56 while (a_swap(&c
->_c_lock
, 1))
57 __wait(&c
->_c_lock
, &c
->_c_lockwait
, 1, 1);
59 a_store(&c
->_c_lock
, 0);
60 if (c
->_c_lockwait
) __wake(&c
->_c_lock
, 1, 1);
65 pthread_mutex_unlock(m
);
67 do e
= __timedwait(&c
->_c_seq
, seq
, c
->_c_clock
, ts
, cleanup
, &cm
, 0);
68 while (c
->_c_seq
== seq
&& (!e
|| e
==EINTR
));
69 if (e
== EINTR
) e
= 0;
73 if ((r
=pthread_mutex_lock(m
))) return r
;