1 /* Internal definitions for pthreads library. 2 Copyright (C) 2016-2022 Free Software Foundation, Inc. 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 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. 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 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with the GNU C Library; if not, see 17 <https://www.gnu.org/licenses/>. */ 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; \ 30 else if (mtxp->__owner_id == self->thread \ 31 && __getpid () == (int)(mtxp->__lock & LLL_OWNER_MASK)) \ 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 \ 45 ret = cb (mtxp->__lock, ##__VA_ARGS__); \ 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) \ 66 ((mtx)->__owner_id == (pt)->thread \ 67 && (((flags) & GSYNC_SHARED) == 0 \ 68 || (mtx)->__shpid == __getpid ())) 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 */ 91