]>
Commit | Line | Data |
---|---|---|
33574c17 | 1 | /* Internal definitions for pthreads library. |
2b778ceb | 2 | Copyright (C) 2016-2021 Free Software Foundation, Inc. |
33574c17 ST |
3 | This file is part of the GNU C Library. |
4 | ||
5 | The GNU C Library is free software; you can redistribute it and/or | |
ad2b41bf ST |
6 | modify it under the terms of the GNU Lesser General Public |
7 | License as published by the Free Software Foundation; either | |
8 | version 2.1 of the License, or (at your option) any later version. | |
33574c17 ST |
9 | |
10 | The GNU C Library is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
ad2b41bf | 13 | Lesser General Public License for more details. |
33574c17 | 14 | |
ad2b41bf ST |
15 | You should have received a copy of the GNU Lesser General Public |
16 | License along with the GNU C Library; if not, see | |
5a82c748 | 17 | <https://www.gnu.org/licenses/>. */ |
33574c17 ST |
18 | |
19 | #ifndef _PT_MUTEX_H | |
20 | #define _PT_MUTEX_H 1 | |
21 | ||
22 | /* Special ID used to signal an unrecoverable robust mutex. */ | |
23 | #define NOTRECOVERABLE_ID (1U << 31) | |
24 | ||
25 | /* Common path for robust mutexes. Assumes the variable 'ret' | |
26 | * is bound in the function this is called from. */ | |
27 | #define ROBUST_LOCK(self, mtxp, cb, ...) \ | |
28 | if (mtxp->__owner_id == NOTRECOVERABLE_ID) \ | |
29 | return ENOTRECOVERABLE; \ | |
aa0e4663 JM |
30 | else if (mtxp->__owner_id == self->thread \ |
31 | && __getpid () == (int)(mtxp->__lock & LLL_OWNER_MASK)) \ | |
33574c17 ST |
32 | { \ |
33 | if (mtxp->__type == PT_MTX_RECURSIVE) \ | |
34 | { \ | |
35 | if (__glibc_unlikely (mtxp->__cnt + 1 == 0)) \ | |
36 | return EAGAIN; \ | |
37 | \ | |
38 | ++mtxp->__cnt; \ | |
39 | return 0; \ | |
40 | } \ | |
41 | else if (mtxp->__type == PT_MTX_ERRORCHECK) \ | |
42 | return EDEADLK; \ | |
43 | } \ | |
44 | \ | |
bec41242 | 45 | ret = cb (mtxp->__lock, ##__VA_ARGS__); \ |
33574c17 ST |
46 | if (ret == 0 || ret == EOWNERDEAD) \ |
47 | { \ | |
48 | if (mtxp->__owner_id == ENOTRECOVERABLE) \ | |
49 | ret = ENOTRECOVERABLE; \ | |
50 | else \ | |
51 | { \ | |
52 | mtxp->__owner_id = self->thread; \ | |
53 | mtxp->__cnt = 1; \ | |
54 | if (ret == EOWNERDEAD) \ | |
55 | { \ | |
56 | mtxp->__lock = mtxp->__lock | LLL_DEAD_OWNER; \ | |
57 | atomic_write_barrier (); \ | |
58 | } \ | |
59 | } \ | |
60 | } \ | |
61 | (void)0 | |
62 | ||
63 | /* Check that a thread owns the mutex. For non-robust, task-shared | |
64 | * objects, we have to check the thread *and* process-id. */ | |
65 | #define mtx_owned_p(mtx, pt, flags) \ | |
aa0e4663 JM |
66 | ((mtx)->__owner_id == (pt)->thread \ |
67 | && (((flags) & GSYNC_SHARED) == 0 \ | |
68 | || (mtx)->__shpid == __getpid ())) | |
33574c17 ST |
69 | |
70 | /* Record a thread as the owner of the mutex. */ | |
71 | #define mtx_set_owner(mtx, pt, flags) \ | |
72 | (void) \ | |
73 | ({ \ | |
74 | (mtx)->__owner_id = (pt)->thread; \ | |
75 | if ((flags) & GSYNC_SHARED) \ | |
76 | (mtx)->__shpid = __getpid (); \ | |
77 | }) | |
78 | ||
79 | /* Redefined mutex types. The +1 is for binary compatibility. */ | |
80 | #define PT_MTX_NORMAL __PTHREAD_MUTEX_TIMED | |
81 | #define PT_MTX_RECURSIVE (__PTHREAD_MUTEX_RECURSIVE + 1) | |
82 | #define PT_MTX_ERRORCHECK (__PTHREAD_MUTEX_ERRORCHECK + 1) | |
83 | ||
84 | /* Mutex type, including robustness. */ | |
85 | #define MTX_TYPE(mtxp) \ | |
86 | ((mtxp)->__type | ((mtxp)->__flags & PTHREAD_MUTEX_ROBUST)) | |
87 | ||
88 | extern int __getpid (void) __attribute__ ((const)); | |
89 | ||
90 | #endif /* pt-mutex.h */ |