1 /* Default mutex implementation struct definitions. 2 Copyright (C) 2019-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 <http://www.gnu.org/licenses/>. */ 18 19 #ifndef _THREAD_MUTEX_INTERNAL_H 20 #define _THREAD_MUTEX_INTERNAL_H 1 21 22 /* Generic struct for both POSIX and C11 mutexes. New ports are expected 23 to use the default layout, however architecture can redefine it to 24 add arch-specific extension (such as lock-elision). The struct have 25 a size of 32 bytes on LP32 and 40 bytes on LP64 architectures. */ 26 27 struct __pthread_mutex_s 28 { 29 int __lock __LOCK_ALIGNMENT; 30 unsigned int __count; 31 int __owner; 32 #if __WORDSIZE == 64 33 unsigned int __nusers; 34 #endif 35 /* KIND must stay at this position in the structure to maintain 36 binary compatibility with static initializers. 37 38 Concurrency notes: 39 The __kind of a mutex is initialized either by the static 40 PTHREAD_MUTEX_INITIALIZER or by a call to pthread_mutex_init. 41 42 After a mutex has been initialized, the __kind of a mutex is usually not 43 changed. BUT it can be set to -1 in pthread_mutex_destroy or elision can 44 be enabled. This is done concurrently in the pthread_mutex_*lock 45 functions by using the macro FORCE_ELISION. This macro is only defined 46 for architectures which supports lock elision. 47 48 For elision, there are the flags PTHREAD_MUTEX_ELISION_NP and 49 PTHREAD_MUTEX_NO_ELISION_NP which can be set in addition to the already 50 set type of a mutex. Before a mutex is initialized, only 51 PTHREAD_MUTEX_NO_ELISION_NP can be set with pthread_mutexattr_settype. 52 53 After a mutex has been initialized, the functions pthread_mutex_*lock can 54 enable elision - if the mutex-type and the machine supports it - by 55 setting the flag PTHREAD_MUTEX_ELISION_NP. This is done concurrently. 56 Afterwards the lock / unlock functions are using specific elision 57 code-paths. */ 58 int __kind; 59 #if __WORDSIZE != 64 60 unsigned int __nusers; 61 #endif 62 #if __WORDSIZE == 64 63 int __spins; 64 __pthread_list_t __list; 65 # define __PTHREAD_MUTEX_HAVE_PREV 1 66 #else 67 __extension__ union 68 { 69 int __spins; 70 __pthread_slist_t __list; 71 }; 72 # define __PTHREAD_MUTEX_HAVE_PREV 0 73 #endif 74 }; 75 76 #if __PTHREAD_MUTEX_HAVE_PREV == 1 77 # define __PTHREAD_MUTEX_INITIALIZER(__kind) \ 78 0, 0, 0, 0, __kind, 0, { 0, 0 } 79 #else 80 # define __PTHREAD_MUTEX_INITIALIZER(__kind) \ 81 0, 0, 0, __kind, 0, { 0 } 82 #endif 83 84 #endif 85