1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
| | #include "pthread_impl.h"
#include <threads.h>
int __thrd_wait(volatile int *addr, int val, const struct timespec *at);
int __mtx_timedlock(__mtx_t *restrict mtx, const struct timespec *restrict at)
{
int r, t;
if (mtx->_mt_typ == PTHREAD_MUTEX_NORMAL && !a_cas(&mtx->_mt_lck, 0, thrd_busy))
return thrd_success;
for (;;) {
r=__mtx_trylock(mtx);
if (r != thrd_busy) return r;
else {
if (!(r=mtx->_mt_lck) || (r&0x40000000)) continue;
a_inc(&mtx->_mt_wts);
t = r | 0x80000000;
a_cas(&mtx->_mt_lck, r, t);
r = __thrd_wait(&mtx->_mt_lck, t, at);
a_dec(&mtx->_mt_wts);
switch (r) {
case 0:
break;
case EINTR:
break;
case EWOULDBLOCK:
break;
case ETIMEDOUT:
return thrd_timedout;
default:
return thrd_error;
}
}
}
}
int mtx_timedlock(mtx_t *restrict mut, const struct timespec *restrict at)
{
__mtx_t * m = __mtx_getref(mut);
if (!m) return thrd_error;
int ret = __mtx_timedlock(m, at);
__mtx_unref(m);
return ret;
}
|