2 * Copyright (c) 2000-2003, 2007, 2008 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
24 * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991
27 * Permission to use, copy, modify, and distribute this software and
28 * its documentation for any purpose and without fee is hereby granted,
29 * provided that the above copyright notice appears in all copies and
30 * that both the copyright notice and this permission notice appear in
31 * supporting documentation.
33 * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
34 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
35 * FOR A PARTICULAR PURPOSE.
37 * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
38 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
39 * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
40 * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
41 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
49 * POSIX Pthread Library
50 * -- Mutex variable support
53 #include "pthread_internals.h"
56 #include "plockstat.h"
57 #else /* !PLOCKSTAT */
58 #define PLOCKSTAT_MUTEX_SPIN(x)
59 #define PLOCKSTAT_MUTEX_SPUN(x, y, z)
60 #define PLOCKSTAT_MUTEX_ERROR(x, y)
61 #define PLOCKSTAT_MUTEX_BLOCK(x)
62 #define PLOCKSTAT_MUTEX_BLOCKED(x, y)
63 #define PLOCKSTAT_MUTEX_ACQUIRE(x, y, z)
64 #define PLOCKSTAT_MUTEX_RELEASE(x, y)
65 #endif /* PLOCKSTAT */
67 extern int __unix_conforming
;
68 extern int __unix_conforming
;
69 int _pthread_mutex_init(pthread_mutex_t
*mutex
, const pthread_mutexattr_t
*attr
);
71 #if defined(__i386__) || defined(__x86_64__)
74 #include <machine/cpu_capabilities.h>
76 extern int _commpage_pthread_mutex_lock(uint32_t * lvalp
, int flags
, uint64_t mtid
, uint32_t mask
, uint64_t * tidp
, int *sysret
);
78 int _new_pthread_mutex_destroy(pthread_mutex_t
*mutex
);
79 int _new_pthread_mutex_destroy_locked(pthread_mutex_t
*mutex
);
80 int _new_pthread_mutex_init(pthread_mutex_t
*mutex
, const pthread_mutexattr_t
*attr
);
81 int _new_pthread_mutex_lock(pthread_mutex_t
*omutex
);
82 int _new_pthread_mutex_trylock(pthread_mutex_t
*omutex
);
83 int _new_pthread_mutex_unlock(pthread_mutex_t
*omutex
);
86 #define MUTEX_GETSEQ_ADDR(mutex, lseqaddr, useqaddr) \
88 if (mutex->mtxopts.options.misalign != 0) { \
89 lseqaddr = &mutex->m_seq[0]; \
90 useqaddr = &mutex->m_seq[1]; \
92 lseqaddr = &mutex->m_seq[1]; \
93 useqaddr = &mutex->m_seq[2]; \
97 #define MUTEX_GETSEQ_ADDR(mutex, lseqaddr, useqaddr) \
99 if (mutex->mtxopts.options.misalign != 0) { \
100 lseqaddr = &mutex->m_seq[1]; \
101 useqaddr = &mutex->m_seq[2]; \
103 lseqaddr = &mutex->m_seq[0]; \
104 useqaddr = &mutex->m_seq[1]; \
107 #endif /* __LP64__ */
109 #define _KSYN_TRACE_ 0
112 /* The Function qualifiers */
113 #define DBG_FUNC_START 1
114 #define DBG_FUNC_END 2
115 #define DBG_FUNC_NONE 0
117 int __kdebug_trace(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t);
119 #define _KSYN_TRACE_UM_LOCK 0x9000060
120 #define _KSYN_TRACE_UM_UNLOCK 0x9000064
121 #define _KSYN_TRACE_UM_MHOLD 0x9000068
122 #define _KSYN_TRACE_UM_MDROP 0x900006c
123 #define _KSYN_TRACE_UM_MUBITS 0x900007c
125 #endif /* _KSYN_TRACE_ */
127 #endif /* __i386__ || __x86_64__ */
129 #ifndef BUILDING_VARIANT /* [ */
131 #define BLOCK_FAIL_PLOCKSTAT 0
132 #define BLOCK_SUCCESS_PLOCKSTAT 1
135 /* 5243343 - temporary hack to detect if we are running the conformance test */
136 extern int PR_5243343_flag
;
137 #endif /* PR_5243343 */
139 /* This function is never called and exists to provide never-fired dtrace
140 * probes so that user d scripts don't get errors.
142 __private_extern__
void _plockstat_never_fired(void)
144 PLOCKSTAT_MUTEX_SPIN(NULL
);
145 PLOCKSTAT_MUTEX_SPUN(NULL
, 0, 0);
149 * Destroy a mutex variable.
152 pthread_mutex_destroy(pthread_mutex_t
*mutex
)
157 if (mutex
->sig
== _PTHREAD_MUTEX_SIG
)
160 #if defined(__i386__) || defined(__x86_64__)
161 if(mutex
->mtxopts
.options
.pshared
== PTHREAD_PROCESS_SHARED
){
163 res
= _new_pthread_mutex_destroy_locked(mutex
);
167 #endif /* __i386__ || __x86_64__ */
169 if (mutex
->owner
== (pthread_t
)NULL
&&
170 mutex
->busy
== (pthread_cond_t
*)NULL
)
172 mutex
->sig
= _PTHREAD_NO_SIG
;
184 * Initialize a mutex variable, possibly with additional attributes.
187 _pthread_mutex_init(pthread_mutex_t
*mutex
, const pthread_mutexattr_t
*attr
)
191 if (attr
->sig
!= _PTHREAD_MUTEX_ATTR_SIG
)
193 #if defined(__i386__) || defined(__x86_64__)
194 if (attr
->pshared
== PTHREAD_PROCESS_SHARED
) {
195 return(_new_pthread_mutex_init(mutex
, attr
));
197 #endif /* __i386__ || __x86_64__ */
199 mutex
->prioceiling
= attr
->prioceiling
;
200 mutex
->mtxopts
.options
.protocol
= attr
->protocol
;
201 mutex
->mtxopts
.options
.policy
= attr
->policy
;
202 mutex
->mtxopts
.options
.type
= attr
->type
;
203 mutex
->mtxopts
.options
.pshared
= attr
->pshared
;
206 mutex
->prioceiling
= _PTHREAD_DEFAULT_PRIOCEILING
;
207 mutex
->mtxopts
.options
.protocol
= _PTHREAD_DEFAULT_PROTOCOL
;
208 mutex
->mtxopts
.options
.policy
= _PTHREAD_MUTEX_POLICY_FAIRSHARE
;
209 mutex
->mtxopts
.options
.type
= PTHREAD_MUTEX_DEFAULT
;
210 mutex
->mtxopts
.options
.pshared
= _PTHREAD_DEFAULT_PSHARED
;
212 mutex
->mtxopts
.options
.lock_count
= 0;
213 mutex
->owner
= (pthread_t
)NULL
;
214 mutex
->next
= (pthread_mutex_t
*)NULL
;
215 mutex
->prev
= (pthread_mutex_t
*)NULL
;
216 mutex
->busy
= (pthread_cond_t
*)NULL
;
218 mutex
->sem
= SEMAPHORE_NULL
;
219 mutex
->order
= SEMAPHORE_NULL
;
220 mutex
->prioceiling
= 0;
221 mutex
->sig
= _PTHREAD_MUTEX_SIG
;
226 * Initialize a mutex variable, possibly with additional attributes.
227 * Public interface - so don't trust the lock - initialize it first.
230 pthread_mutex_init(pthread_mutex_t
*mutex
, const pthread_mutexattr_t
*attr
)
233 /* conformance tests depend on not having this behavior */
234 /* The test for this behavior is optional */
235 if (mutex
->sig
== _PTHREAD_MUTEX_SIG
)
238 LOCK_INIT(mutex
->lock
);
239 return (_pthread_mutex_init(mutex
, attr
));
244 * TODO: Priority inheritance stuff
247 pthread_mutex_lock(pthread_mutex_t
*mutex
)
249 kern_return_t kern_res
;
251 int sig
= mutex
->sig
;
253 /* To provide backwards compat for apps using mutex incorrectly */
254 if ((sig
!= _PTHREAD_MUTEX_SIG
) && (sig
!= _PTHREAD_MUTEX_SIG_init
)) {
255 PLOCKSTAT_MUTEX_ERROR(mutex
, EINVAL
);
260 if (mutex
->sig
!= _PTHREAD_MUTEX_SIG
)
262 if (mutex
->sig
!= _PTHREAD_MUTEX_SIG_init
)
265 PLOCKSTAT_MUTEX_ERROR(mutex
, EINVAL
);
268 _pthread_mutex_init(mutex
, NULL
);
269 self
= _PTHREAD_MUTEX_OWNER_SELF
;
271 #if defined(__i386__) || defined(__x86_64__)
272 else if(mutex
->mtxopts
.options
.pshared
== PTHREAD_PROCESS_SHARED
){
274 return(_new_pthread_mutex_lock(mutex
));
276 #endif /* __i386__ || __x86_64__ */
277 else if (mutex
->mtxopts
.options
.type
!= PTHREAD_MUTEX_NORMAL
)
279 self
= pthread_self();
280 if (mutex
->owner
== self
)
284 if (mutex
->mtxopts
.options
.type
== PTHREAD_MUTEX_RECURSIVE
)
286 if (mutex
->mtxopts
.options
.lock_count
< USHRT_MAX
)
288 mutex
->mtxopts
.options
.lock_count
++;
289 PLOCKSTAT_MUTEX_ACQUIRE(mutex
, 1, 0);
293 PLOCKSTAT_MUTEX_ERROR(mutex
, res
);
295 } else { /* PTHREAD_MUTEX_ERRORCHECK */
297 PLOCKSTAT_MUTEX_ERROR(mutex
, res
);
303 self
= _PTHREAD_MUTEX_OWNER_SELF
;
305 if (mutex
->owner
!= (pthread_t
)NULL
) {
306 if (mutex
->waiters
|| mutex
->owner
!= _PTHREAD_MUTEX_OWNER_SWITCHING
)
308 semaphore_t sem
, order
;
310 if (++mutex
->waiters
== 1)
312 mutex
->sem
= sem
= new_sem_from_pool();
313 mutex
->order
= order
= new_sem_from_pool();
318 order
= mutex
->order
;
320 PTHREAD_MACH_CALL(semaphore_wait(order
), kern_res
);
321 } while (kern_res
== KERN_ABORTED
);
325 PLOCKSTAT_MUTEX_BLOCK(mutex
);
326 PTHREAD_MACH_CALL(semaphore_wait_signal(sem
, order
), kern_res
);
327 while (kern_res
== KERN_ABORTED
)
329 PTHREAD_MACH_CALL(semaphore_wait(sem
), kern_res
);
332 PLOCKSTAT_MUTEX_BLOCKED(mutex
, BLOCK_SUCCESS_PLOCKSTAT
);
335 if (--mutex
->waiters
== 0)
337 PTHREAD_MACH_CALL(semaphore_wait(order
), kern_res
);
338 mutex
->sem
= mutex
->order
= SEMAPHORE_NULL
;
339 restore_sem_to_pool(order
);
340 restore_sem_to_pool(sem
);
343 else if (mutex
->owner
== _PTHREAD_MUTEX_OWNER_SWITCHING
)
345 semaphore_t sem
= mutex
->sem
;
347 PTHREAD_MACH_CALL(semaphore_wait(sem
), kern_res
);
348 } while (kern_res
== KERN_ABORTED
);
349 mutex
->sem
= SEMAPHORE_NULL
;
350 restore_sem_to_pool(sem
);
354 mutex
->mtxopts
.options
.lock_count
= 1;
357 PLOCKSTAT_MUTEX_ACQUIRE(mutex
, 0, 0);
362 * Attempt to lock a mutex, but don't block if this isn't possible.
365 pthread_mutex_trylock(pthread_mutex_t
*mutex
)
367 kern_return_t kern_res
;
371 if (mutex
->sig
!= _PTHREAD_MUTEX_SIG
)
373 if (mutex
->sig
!= _PTHREAD_MUTEX_SIG_init
)
375 PLOCKSTAT_MUTEX_ERROR(mutex
, EINVAL
);
379 _pthread_mutex_init(mutex
, NULL
);
380 self
= _PTHREAD_MUTEX_OWNER_SELF
;
382 #if defined(__i386__) || defined(__x86_64__)
383 else if(mutex
->mtxopts
.options
.pshared
== PTHREAD_PROCESS_SHARED
){
385 return(_new_pthread_mutex_trylock(mutex
));
387 #endif /* __i386__ || __x86_64__ */
388 else if (mutex
->mtxopts
.options
.type
!= PTHREAD_MUTEX_NORMAL
)
390 self
= pthread_self();
391 if (mutex
->mtxopts
.options
.type
== PTHREAD_MUTEX_RECURSIVE
)
393 if (mutex
->owner
== self
)
397 if (mutex
->mtxopts
.options
.lock_count
< USHRT_MAX
)
399 mutex
->mtxopts
.options
.lock_count
++;
400 PLOCKSTAT_MUTEX_ACQUIRE(mutex
, 1, 0);
404 PLOCKSTAT_MUTEX_ERROR(mutex
, res
);
411 self
= _PTHREAD_MUTEX_OWNER_SELF
;
413 if (mutex
->owner
!= (pthread_t
)NULL
)
415 if (mutex
->waiters
|| mutex
->owner
!= _PTHREAD_MUTEX_OWNER_SWITCHING
)
417 PLOCKSTAT_MUTEX_ERROR(mutex
, EBUSY
);
421 else if (mutex
->owner
== _PTHREAD_MUTEX_OWNER_SWITCHING
)
423 semaphore_t sem
= mutex
->sem
;
426 PTHREAD_MACH_CALL(semaphore_wait(sem
), kern_res
);
427 } while (kern_res
== KERN_ABORTED
);
428 restore_sem_to_pool(sem
);
429 mutex
->sem
= SEMAPHORE_NULL
;
433 mutex
->mtxopts
.options
.lock_count
= 1;
436 PLOCKSTAT_MUTEX_ACQUIRE(mutex
, 0, 0);
442 * TODO: Priority inheritance stuff
445 pthread_mutex_unlock(pthread_mutex_t
*mutex
)
447 kern_return_t kern_res
;
449 int sig
= mutex
->sig
;
452 /* To provide backwards compat for apps using mutex incorrectly */
454 if ((sig
!= _PTHREAD_MUTEX_SIG
) && (sig
!= _PTHREAD_MUTEX_SIG_init
)) {
455 PLOCKSTAT_MUTEX_ERROR(mutex
, EINVAL
);
459 if (mutex
->sig
!= _PTHREAD_MUTEX_SIG
)
461 if (mutex
->sig
!= _PTHREAD_MUTEX_SIG_init
)
463 PLOCKSTAT_MUTEX_ERROR(mutex
, EINVAL
);
467 _pthread_mutex_init(mutex
, NULL
);
469 #if defined(__i386__) || defined(__x86_64__)
470 else if(mutex
->mtxopts
.options
.pshared
== PTHREAD_PROCESS_SHARED
){
472 return(_new_pthread_mutex_unlock(mutex
));
474 #endif /* __i386__ || __x86_64__ */
475 else if (mutex
->mtxopts
.options
.type
!= PTHREAD_MUTEX_NORMAL
)
477 pthread_t self
= pthread_self();
478 if (mutex
->owner
!= self
)
480 PLOCKSTAT_MUTEX_ERROR(mutex
, EPERM
);
483 } else if (mutex
->mtxopts
.options
.type
== PTHREAD_MUTEX_RECURSIVE
&&
484 --mutex
->mtxopts
.options
.lock_count
)
486 PLOCKSTAT_MUTEX_RELEASE(mutex
, 1);
492 mutex
->mtxopts
.options
.lock_count
= 0;
494 waiters
= mutex
->waiters
;
497 mutex
->owner
= _PTHREAD_MUTEX_OWNER_SWITCHING
;
498 PLOCKSTAT_MUTEX_RELEASE(mutex
, 0);
500 PTHREAD_MACH_CALL(semaphore_signal(mutex
->sem
), kern_res
);
504 mutex
->owner
= (pthread_t
)NULL
;
505 PLOCKSTAT_MUTEX_RELEASE(mutex
, 0);
512 * Fetch the priority ceiling value from a mutex variable.
513 * Note: written as a 'helper' function to hide implementation details.
516 pthread_mutex_getprioceiling(const pthread_mutex_t
*mutex
,
522 if (mutex
->sig
== _PTHREAD_MUTEX_SIG
)
524 *prioceiling
= mutex
->prioceiling
;
527 res
= EINVAL
; /* Not an initialized 'attribute' structure */
533 * Set the priority ceiling for a mutex.
534 * Note: written as a 'helper' function to hide implementation details.
537 pthread_mutex_setprioceiling(pthread_mutex_t
*mutex
,
539 int *old_prioceiling
)
544 if (mutex
->sig
== _PTHREAD_MUTEX_SIG
)
546 if ((prioceiling
>= -999) ||
547 (prioceiling
<= 999))
549 *old_prioceiling
= mutex
->prioceiling
;
550 mutex
->prioceiling
= prioceiling
;
553 res
= EINVAL
; /* Invalid parameter */
555 res
= EINVAL
; /* Not an initialized 'attribute' structure */
561 * Get the priority ceiling value from a mutex attribute structure.
562 * Note: written as a 'helper' function to hide implementation details.
565 pthread_mutexattr_getprioceiling(const pthread_mutexattr_t
*attr
,
568 if (attr
->sig
== _PTHREAD_MUTEX_ATTR_SIG
)
570 *prioceiling
= attr
->prioceiling
;
574 return (EINVAL
); /* Not an initialized 'attribute' structure */
579 * Get the mutex 'protocol' value from a mutex attribute structure.
580 * Note: written as a 'helper' function to hide implementation details.
583 pthread_mutexattr_getprotocol(const pthread_mutexattr_t
*attr
,
586 if (attr
->sig
== _PTHREAD_MUTEX_ATTR_SIG
)
588 *protocol
= attr
->protocol
;
592 return (EINVAL
); /* Not an initialized 'attribute' structure */
596 * Get the mutex 'type' value from a mutex attribute structure.
597 * Note: written as a 'helper' function to hide implementation details.
600 pthread_mutexattr_gettype(const pthread_mutexattr_t
*attr
,
603 if (attr
->sig
== _PTHREAD_MUTEX_ATTR_SIG
)
609 return (EINVAL
); /* Not an initialized 'attribute' structure */
617 pthread_mutexattr_getpshared(const pthread_mutexattr_t
*attr
, int *pshared
)
619 if (attr
->sig
== _PTHREAD_MUTEX_ATTR_SIG
)
621 *pshared
= (int)attr
->pshared
;
625 return (EINVAL
); /* Not an initialized 'attribute' structure */
630 * Initialize a mutex attribute structure to system defaults.
633 pthread_mutexattr_init(pthread_mutexattr_t
*attr
)
635 attr
->prioceiling
= _PTHREAD_DEFAULT_PRIOCEILING
;
636 attr
->protocol
= _PTHREAD_DEFAULT_PROTOCOL
;
637 attr
->policy
= _PTHREAD_MUTEX_POLICY_FAIRSHARE
;
638 attr
->type
= PTHREAD_MUTEX_DEFAULT
;
639 attr
->sig
= _PTHREAD_MUTEX_ATTR_SIG
;
640 attr
->pshared
= _PTHREAD_DEFAULT_PSHARED
;
645 * Set the priority ceiling value in a mutex attribute structure.
646 * Note: written as a 'helper' function to hide implementation details.
649 pthread_mutexattr_setprioceiling(pthread_mutexattr_t
*attr
,
652 if (attr
->sig
== _PTHREAD_MUTEX_ATTR_SIG
)
654 if ((prioceiling
>= -999) ||
655 (prioceiling
<= 999))
657 attr
->prioceiling
= prioceiling
;
661 return (EINVAL
); /* Invalid parameter */
665 return (EINVAL
); /* Not an initialized 'attribute' structure */
670 * Set the mutex 'protocol' value in a mutex attribute structure.
671 * Note: written as a 'helper' function to hide implementation details.
674 pthread_mutexattr_setprotocol(pthread_mutexattr_t
*attr
,
677 if (attr
->sig
== _PTHREAD_MUTEX_ATTR_SIG
)
679 if ((protocol
== PTHREAD_PRIO_NONE
) ||
680 (protocol
== PTHREAD_PRIO_INHERIT
) ||
681 (protocol
== PTHREAD_PRIO_PROTECT
))
683 attr
->protocol
= protocol
;
687 return (EINVAL
); /* Invalid parameter */
691 return (EINVAL
); /* Not an initialized 'attribute' structure */
697 pthread_mutexattr_setpolicy_np(pthread_mutexattr_t
*attr
,
700 if (attr
->sig
== _PTHREAD_MUTEX_ATTR_SIG
)
702 if ((policy
== _PTHREAD_MUTEX_POLICY_FAIRSHARE
) ||
703 (policy
== _PTHREAD_MUTEX_POLICY_FIRSTFIT
) ||
704 (policy
== _PTHREAD_MUTEX_POLICY_REALTIME
) ||
705 (policy
== _PTHREAD_MUTEX_POLICY_ADAPTIVE
) ||
706 (policy
== _PTHREAD_MUTEX_POLICY_PRIPROTECT
) ||
707 (policy
== _PTHREAD_MUTEX_POLICY_PRIINHERIT
))
709 attr
->policy
= policy
;
713 return (EINVAL
); /* Invalid parameter */
717 return (EINVAL
); /* Not an initialized 'attribute' structure */
723 * Set the mutex 'type' value in a mutex attribute structure.
724 * Note: written as a 'helper' function to hide implementation details.
727 pthread_mutexattr_settype(pthread_mutexattr_t
*attr
,
730 if (attr
->sig
== _PTHREAD_MUTEX_ATTR_SIG
)
732 if ((type
== PTHREAD_MUTEX_NORMAL
) ||
733 (type
== PTHREAD_MUTEX_ERRORCHECK
) ||
734 (type
== PTHREAD_MUTEX_RECURSIVE
) ||
735 (type
== PTHREAD_MUTEX_DEFAULT
))
741 return (EINVAL
); /* Invalid parameter */
745 return (EINVAL
); /* Not an initialized 'attribute' structure */
750 int mutex_try_lock(int *x
) {
751 return _spin_lock_try((pthread_lock_t
*)x
);
754 void mutex_wait_lock(int *x
) {
756 if( _spin_lock_try((pthread_lock_t
*)x
)) {
770 pthread_yield_np (void)
777 * Temp: till pshared is fixed correctly
780 pthread_mutexattr_setpshared(pthread_mutexattr_t
*attr
, int pshared
)
783 if (__unix_conforming
== 0)
784 __unix_conforming
= 1;
785 #endif /* __DARWIN_UNIX03 */
787 if (attr
->sig
== _PTHREAD_MUTEX_ATTR_SIG
)
791 if (( pshared
== PTHREAD_PROCESS_PRIVATE
) || (pshared
== PTHREAD_PROCESS_SHARED
&& PR_5243343_flag
))
792 #else /* !PR_5243343 */
793 if (( pshared
== PTHREAD_PROCESS_PRIVATE
) || (pshared
== PTHREAD_PROCESS_SHARED
))
794 #endif /* PR_5243343 */
795 #else /* __DARWIN_UNIX03 */
796 if ( pshared
== PTHREAD_PROCESS_PRIVATE
)
797 #endif /* __DARWIN_UNIX03 */
799 attr
->pshared
= pshared
;
803 return (EINVAL
); /* Invalid parameter */
807 return (EINVAL
); /* Not an initialized 'attribute' structure */
811 #if defined(__i386__) || defined(__x86_64__)
814 * Acquire lock seq for condition var signalling/broadcast
816 __private_extern__
void
817 __mtx_holdlock(npthread_mutex_t
* mutex
, uint32_t diff
, uint32_t * flagp
, uint32_t **pmtxp
, uint32_t * mgenp
, uint32_t * ugenp
)
819 uint32_t mgen
, ugen
, ngen
;
821 int firstfit
= (mutex
->mtxopts
.options
.policy
== _PTHREAD_MUTEX_POLICY_FIRSTFIT
);
827 (void)__kdebug_trace(_KSYN_TRACE_UM_MHOLD
| DBG_FUNC_START
, (uint32_t)mutex
, diff
, firstfit
, 0, 0);
829 if (mutex
->mtxopts
.options
.pshared
== PTHREAD_PROCESS_SHARED
) {
830 /* no holds for shared mutexes */
834 MUTEX_GETSEQ_ADDR(mutex
, lseqaddr
, useqaddr
);
837 lseqaddr
= mutex
->m_lseqaddr
;
838 useqaddr
= mutex
->m_useqaddr
;
844 /* no need to do extra wrap */
845 ngen
= mgen
+ (PTHRW_INC
* diff
);
850 (void)__kdebug_trace(_KSYN_TRACE_UM_MHOLD
| DBG_FUNC_NONE
, (uint32_t)mutex
, 0, mgen
, ngen
, 0);
852 /* can we acquire the lock ? */
853 if ((mgen
& PTHRW_EBIT
) == 0) {
854 /* if it is firstfit, no need to hold till the cvar returns */
860 (void)__kdebug_trace(_KSYN_TRACE_UM_MHOLD
| DBG_FUNC_NONE
, (uint32_t)mutex
, 1, mgen
, ngen
, 0);
865 if (OSAtomicCompareAndSwap32(mgen
, ngen
, (volatile int32_t *)lseqaddr
) != TRUE
)
868 mutex
->m_tid
= PTHREAD_MTX_TID_SWITCHING
;
871 (void)__kdebug_trace(_KSYN_TRACE_UM_MHOLD
| DBG_FUNC_NONE
, (uint32_t)mutex
, 2, hold
, 0, 0);
877 *flagp
= (mutex
->mtxopts
.value
| _PTHREAD_MTX_OPT_HOLD
);
878 } else if (hold
== 2) {
879 *flagp
= (mutex
->mtxopts
.value
| _PTHREAD_MTX_OPT_NOHOLD
);
881 *flagp
= mutex
->mtxopts
.value
;
891 (void)__kdebug_trace(_KSYN_TRACE_UM_MHOLD
| DBG_FUNC_END
, (uint32_t)mutex
, hold
, 0, 0, 0);
897 * Drop the mutex unlock references(from cond wait or mutex_unlock().
898 * mgenp and ugenp valid only if notifyp is set
901 __private_extern__
int
902 __mtx_droplock(npthread_mutex_t
* mutex
, int count
, uint32_t * flagp
, uint32_t ** pmtxp
, uint32_t * mgenp
, uint32_t * ugenp
, uint32_t *notifyp
)
904 int oldval
, newval
, lockval
, unlockval
;
906 pthread_t self
= pthread_self();
908 uint64_t oldval64
, newval64
;
911 int firstfit
= (mutex
->mtxopts
.options
.policy
== _PTHREAD_MUTEX_POLICY_FIRSTFIT
);
914 (void)__kdebug_trace(_KSYN_TRACE_UM_MDROP
| DBG_FUNC_START
, (uint32_t)mutex
, count
, 0, 0, 0);
916 if (mutex
->mtxopts
.options
.pshared
== PTHREAD_PROCESS_SHARED
) {
917 MUTEX_GETSEQ_ADDR(mutex
, lseqaddr
, useqaddr
);
919 lseqaddr
= mutex
->m_lseqaddr
;
920 useqaddr
= mutex
->m_useqaddr
;
924 *flagp
= mutex
->mtxopts
.value
;
927 notify
|= 0x80000000;
928 if (mutex
->mtxopts
.options
.pshared
== PTHREAD_PROCESS_SHARED
)
929 notify
|= 0x40000000;
931 if (mutex
->mtxopts
.options
.type
!= PTHREAD_MUTEX_NORMAL
)
933 if (mutex
->m_tid
!= (uint64_t)((uintptr_t)self
))
935 PLOCKSTAT_MUTEX_ERROR((pthread_mutex_t
*)mutex
, EPERM
);
937 } else if (mutex
->mtxopts
.options
.type
== PTHREAD_MUTEX_RECURSIVE
&&
938 --mutex
->mtxopts
.options
.lock_count
)
940 PLOCKSTAT_MUTEX_RELEASE((pthread_mutex_t
*)mutex
, 1);
946 if (mutex
->m_tid
!= (uint64_t)((uintptr_t)self
))
952 unlockval
= oldval
+ (PTHRW_INC
* count
);
957 (void)__kdebug_trace(_KSYN_TRACE_UM_MDROP
| DBG_FUNC_NONE
, (uint32_t)mutex
, 10, lockval
, oldval
, 0);
960 if (lockval
== oldval
)
961 LIBC_ABORT("same unlock and lockseq \n");
964 if ((lockval
& PTHRW_COUNT_MASK
) == unlockval
) {
965 oldtid
= mutex
->m_tid
;
969 oldval64
= (((uint64_t)oldval
) << 32);
974 if (OSAtomicCompareAndSwap64(oldval64
, newval64
, (volatile int64_t *)lseqaddr
) == TRUE
) {
976 (void)__kdebug_trace(_KSYN_TRACE_UM_MDROP
| DBG_FUNC_NONE
, (uint32_t)mutex
, 1, 0, 0, 0);
980 mutex
->m_tid
= oldtid
;
981 /* fall thru for kernel call */
987 /* reset ebit along with unlock */
988 newval
= (lockval
& ~PTHRW_EBIT
);
991 oldval64
= (((uint64_t)oldval
) << 32);
994 newval64
= (((uint64_t)unlockval
) << 32);
997 if (OSAtomicCompareAndSwap64(oldval64
, newval64
, (volatile int64_t *)lseqaddr
) != TRUE
) {
1002 /* fairshare , just update and go to kernel */
1003 if (OSAtomicCompareAndSwap32(oldval
, unlockval
, (volatile int32_t *)useqaddr
) != TRUE
)
1007 (void)__kdebug_trace(_KSYN_TRACE_UM_MDROP
| DBG_FUNC_NONE
, (uint32_t)mutex
, 2, oldval
, unlockval
, 0);
1027 (void)__kdebug_trace(_KSYN_TRACE_UM_MDROP
| DBG_FUNC_END
, (uint32_t)mutex
, 0, 0, 0, 0);
1033 __mtx_updatebits(npthread_mutex_t
*mutex
, uint32_t oupdateval
, int firstfit
, int fromcond
)
1035 uint32_t lgenval
, newval
, bits
;
1037 uint32_t updateval
= oupdateval
;
1038 pthread_mutex_t
* omutex
= (pthread_mutex_t
*)mutex
;
1039 uint32_t * lseqaddr
;
1040 uint32_t * useqaddr
;
1042 if (mutex
->mtxopts
.options
.pshared
== PTHREAD_PROCESS_SHARED
) {
1043 MUTEX_GETSEQ_ADDR(mutex
, lseqaddr
, useqaddr
);
1045 lseqaddr
= mutex
->m_lseqaddr
;
1046 useqaddr
= mutex
->m_useqaddr
;
1049 (void)__kdebug_trace(_KSYN_TRACE_UM_MUBITS
| DBG_FUNC_START
, (uint32_t)mutex
, oupdateval
, firstfit
, fromcond
, 0);
1053 lgenval
= *lseqaddr
;
1054 bits
= updateval
& PTHRW_BIT_MASK
;
1056 if (lgenval
== updateval
)
1060 (void)__kdebug_trace(_KSYN_TRACE_UM_MUBITS
| DBG_FUNC_NONE
, (uint32_t)mutex
, 1, lgenval
, updateval
, 0);
1062 if ((lgenval
& PTHRW_BIT_MASK
) == bits
)
1066 (void)__kdebug_trace(_KSYN_TRACE_UM_MUBITS
| DBG_FUNC_NONE
, (uint32_t)mutex
, 2, lgenval
, bits
, 0);
1068 /* firsfit might not have EBIT */
1069 if (firstfit
!= 0) {
1070 lgenval
&= ~PTHRW_EBIT
; /* see whether EBIT is set */
1071 if ((lgenval
& PTHRW_EBIT
) != 0)
1075 if ((lgenval
& PTHRW_COUNT_MASK
) == (updateval
& PTHRW_COUNT_MASK
)) {
1077 (void)__kdebug_trace(_KSYN_TRACE_UM_MUBITS
| DBG_FUNC_NONE
, (uint32_t)mutex
, 3, lgenval
, updateval
, 0);
1079 updateval
|= PTHRW_EBIT
; /* just in case.. */
1080 if (OSAtomicCompareAndSwap32(lgenval
, updateval
, (volatile int32_t *)lseqaddr
) != TRUE
) {
1085 /* update succesfully */
1090 if (((lgenval
& PTHRW_WBIT
) != 0) && ((updateval
& PTHRW_WBIT
) == 0)) {
1091 newval
= lgenval
| (bits
| PTHRW_WBIT
| PTHRW_EBIT
);
1093 newval
= lgenval
| (bits
| PTHRW_EBIT
);
1097 (void)__kdebug_trace(_KSYN_TRACE_UM_MUBITS
| DBG_FUNC_NONE
, (uint32_t)mutex
, 4, lgenval
, newval
, 0);
1099 if (OSAtomicCompareAndSwap32(lgenval
, newval
, (volatile int32_t *)lseqaddr
) != TRUE
) {
1105 /* succesful bits updation */
1106 mutex
->m_tid
= (uint64_t)((uintptr_t)pthread_self());
1108 (void)__kdebug_trace(_KSYN_TRACE_UM_MUBITS
| DBG_FUNC_END
, (uint32_t)mutex
, 0, 0, 0, 0);
1113 /* firstfit failure */
1115 if ((newval
& PTHRW_EBIT
) == 0)
1117 if (((lgenval
& PTHRW_COUNT_MASK
) == (newval
& PTHRW_COUNT_MASK
)) && (isebit
== 1)) {
1121 /* called from condition variable code block again */
1123 #if USE_COMPAGE /* [ */
1124 updateval
= __psynch_mutexwait((pthread_mutex_t
*)lseqaddr
, newval
| PTHRW_RETRYBIT
, *useqaddr
, (uint64_t)0,
1125 mutex
->mtxopts
.value
);
1126 #else /* USECOMPAGE ][ */
1127 updateval
= __psynch_mutexwait(omutex
, newval
| PTHRW_RETRYBIT
, *useqaddr
, (uint64_t)0,
1128 #endif /* USE_COMPAGE ] */
1129 if (updateval
== (uint32_t)-1) {
1136 /* seqcount changed, retry */
1141 _new_pthread_mutex_lock(pthread_mutex_t
*omutex
)
1144 npthread_mutex_t
* mutex
= (npthread_mutex_t
*)omutex
;
1145 int sig
= mutex
->sig
;
1147 uint32_t oldval
, newval
, uval
, updateval
;
1151 uint32_t * lseqaddr
;
1152 uint32_t * useqaddr
;
1153 int updatebitsonly
= 0;
1162 /* To provide backwards compat for apps using mutex incorrectly */
1163 if ((sig
!= _PTHREAD_MUTEX_SIG
) && (sig
!= _PTHREAD_MUTEX_SIG_init
)) {
1164 PLOCKSTAT_MUTEX_ERROR(omutex
, EINVAL
);
1167 if (sig
!= _PTHREAD_MUTEX_SIG
) {
1169 if ((sig
!= _PTHREAD_MUTEX_SIG
) && (sig
== _PTHREAD_MUTEX_SIG_init
)) {
1170 /* static initializer, init the mutex */
1171 _new_pthread_mutex_init(omutex
, NULL
);
1172 self
= _PTHREAD_MUTEX_OWNER_SELF
;
1174 UNLOCK(mutex
->lock
);
1175 PLOCKSTAT_MUTEX_ERROR(omutex
, EINVAL
);
1178 UNLOCK(mutex
->lock
);
1182 (void)__kdebug_trace(_KSYN_TRACE_UM_LOCK
| DBG_FUNC_START
, (uint32_t)mutex
, 0, 0, 0, 0);
1184 if (mutex
->mtxopts
.options
.pshared
== PTHREAD_PROCESS_SHARED
) {
1185 MUTEX_GETSEQ_ADDR(mutex
, lseqaddr
, useqaddr
);
1187 lseqaddr
= mutex
->m_lseqaddr
;
1188 useqaddr
= mutex
->m_useqaddr
;
1191 self
= pthread_self();
1192 if (mutex
->mtxopts
.options
.type
!= PTHREAD_MUTEX_NORMAL
) {
1193 if (mutex
->m_tid
== (uint64_t)((uintptr_t)self
)) {
1194 if (mutex
->mtxopts
.options
.type
== PTHREAD_MUTEX_RECURSIVE
)
1196 if (mutex
->mtxopts
.options
.lock_count
< USHRT_MAX
)
1198 mutex
->mtxopts
.options
.lock_count
++;
1199 PLOCKSTAT_MUTEX_ACQUIRE(omutex
, 1, 0);
1203 PLOCKSTAT_MUTEX_ERROR(omutex
, retval
);
1205 } else { /* PTHREAD_MUTEX_ERRORCHECK */
1207 PLOCKSTAT_MUTEX_ERROR(omutex
, retval
);
1213 (void)__kdebug_trace(_KSYN_TRACE_UM_LOCK
| DBG_FUNC_NONE
, (uint32_t)mutex
, 1, 0, 0, 0);
1216 #if USE_COMPAGE /* [ */
1218 mytid
= (uint64_t)((uintptr_t)pthread_self());
1222 retval
= _commpage_pthread_mutex_lock(lseqaddr
, mutex
->mtxopts
.value
, mytid
, mask
, &mutex
->m_tid
, &sysret
);
1225 } else if (retval
== 1) {
1228 /* returns 0 on succesful update */
1229 if (__mtx_updatebits( mutex
, updateval
, firstfit
, 0) == 1) {
1230 /* could not acquire, may be locked in ffit case */
1232 LIBC_ABORT("comapge implementatin looping in libc \n");
1238 else if (retval
== 3) {
1239 cthread_set_errno_self(sysret
);
1242 newval
= oldval
+ PTHRW_INC
;
1244 /* to block in the kerenl again */
1248 LIBC_ABORT("comapge implementatin bombed \n");
1252 #else /* USECOMPAGE ][ */
1255 newval
= oldval
+ PTHRW_INC
;
1257 (void)__kdebug_trace(_KSYN_TRACE_UM_LOCK
| DBG_FUNC_NONE
, (uint32_t)mutex
, 2, oldval
, uval
, 0);
1259 if((oldval
& PTHRW_EBIT
) == 0) {
1261 newval
|= PTHRW_EBIT
;
1264 newval
|= PTHRW_WBIT
;
1267 if (OSAtomicCompareAndSwap32(oldval
, newval
, (volatile int32_t *)lseqaddr
) == TRUE
) {
1269 mutex
->m_tid
= (uint64_t)((uintptr_t)self
);
1271 (void)__kdebug_trace(_KSYN_TRACE_UM_LOCK
| DBG_FUNC_NONE
, (uint32_t)mutex
, 2, oldval
, newval
, 0);
1280 (void)__kdebug_trace(_KSYN_TRACE_UM_LOCK
| DBG_FUNC_NONE
, (uint32_t)mutex
, 3, 0, 0, 0);
1282 firstfit
= (mutex
->mtxopts
.options
.policy
== _PTHREAD_MUTEX_POLICY_FIRSTFIT
);
1284 updateval
= __psynch_mutexwait(omutex
, newval
| retrybit
, uval
, (uint64_t)0,
1285 mutex
->mtxopts
.value
);
1287 if (updateval
== (uint32_t)-1) {
1293 (void)__kdebug_trace(_KSYN_TRACE_UM_LOCK
| DBG_FUNC_NONE
, (uint32_t)mutex
, 4, updateval
, 0, 0);
1295 /* returns 0 on succesful update */
1296 if (__mtx_updatebits( mutex
, updateval
, firstfit
, 0) == 1) {
1297 /* could not acquire, may be locked in ffit case */
1298 retrybit
= PTHRW_RETRYBIT
;
1300 LIBC_ABORT("comapge implementatin looping in libc \n");
1306 #endif /* USE_COMPAGE ] */
1308 if (mutex
->mtxopts
.options
.type
== PTHREAD_MUTEX_RECURSIVE
)
1309 mutex
->mtxopts
.options
.lock_count
++;
1312 (void)__kdebug_trace(_KSYN_TRACE_UM_LOCK
| DBG_FUNC_END
, (uint32_t)mutex
, 0, 0, 0, 0);
1318 * Attempt to lock a mutex, but don't block if this isn't possible.
1321 _new_pthread_mutex_trylock(pthread_mutex_t
*omutex
)
1323 npthread_mutex_t
* mutex
= (npthread_mutex_t
*)omutex
;
1324 int sig
= mutex
->sig
;
1325 uint32_t oldval
, newval
;
1328 uint32_t * lseqaddr
;
1329 uint32_t * useqaddr
;
1331 /* To provide backwards compat for apps using mutex incorrectly */
1332 if ((sig
!= _PTHREAD_MUTEX_SIG
) && (sig
!= _PTHREAD_MUTEX_SIG_init
)) {
1333 PLOCKSTAT_MUTEX_ERROR(omutex
, EINVAL
);
1337 if (sig
!= _PTHREAD_MUTEX_SIG
) {
1339 if ((sig
!= _PTHREAD_MUTEX_SIG
) && (sig
== _PTHREAD_MUTEX_SIG_init
)) {
1340 /* static initializer, init the mutex */
1341 _new_pthread_mutex_init(omutex
, NULL
);
1342 self
= _PTHREAD_MUTEX_OWNER_SELF
;
1344 UNLOCK(mutex
->lock
);
1345 PLOCKSTAT_MUTEX_ERROR(omutex
, EINVAL
);
1348 UNLOCK(mutex
->lock
);
1351 if (mutex
->mtxopts
.options
.pshared
== PTHREAD_PROCESS_SHARED
) {
1352 MUTEX_GETSEQ_ADDR(mutex
, lseqaddr
, useqaddr
);
1354 lseqaddr
= mutex
->m_lseqaddr
;
1355 useqaddr
= mutex
->m_useqaddr
;
1358 self
= pthread_self();
1359 if (mutex
->mtxopts
.options
.type
!= PTHREAD_MUTEX_NORMAL
) {
1360 if (mutex
->m_tid
== (uint64_t)((uintptr_t)self
)) {
1361 if (mutex
->mtxopts
.options
.type
== PTHREAD_MUTEX_RECURSIVE
)
1363 if (mutex
->mtxopts
.options
.lock_count
< USHRT_MAX
)
1365 mutex
->mtxopts
.options
.lock_count
++;
1366 PLOCKSTAT_MUTEX_ACQUIRE(omutex
, 1, 0);
1370 PLOCKSTAT_MUTEX_ERROR(omutex
, error
);
1372 } else { /* PTHREAD_MUTEX_ERRORCHECK */
1374 PLOCKSTAT_MUTEX_ERROR(omutex
, error
);
1382 if ((oldval
& PTHRW_EBIT
) != 0) {
1383 newval
= oldval
| PTHRW_TRYLKBIT
;
1384 if (OSAtomicCompareAndSwap32(oldval
, newval
, (volatile int32_t *)lseqaddr
) == TRUE
) {
1389 newval
= (oldval
+ PTHRW_INC
)| PTHRW_EBIT
;
1390 if ((OSAtomicCompareAndSwap32(oldval
, newval
, (volatile int32_t *)lseqaddr
) == TRUE
)) {
1391 mutex
->m_tid
= (uint64_t)((uintptr_t)self
);
1392 if (mutex
->mtxopts
.options
.type
== PTHREAD_MUTEX_RECURSIVE
)
1393 mutex
->mtxopts
.options
.lock_count
++;
1403 * TODO: Priority inheritance stuff
1406 _new_pthread_mutex_unlock(pthread_mutex_t
*omutex
)
1408 npthread_mutex_t
* mutex
= (npthread_mutex_t
*)omutex
;
1410 uint32_t mtxgen
, mtxugen
, flags
, notify
;
1411 int sig
= mutex
->sig
;
1412 pthread_t self
= pthread_self();
1413 uint32_t * lseqaddr
;
1414 uint32_t * useqaddr
;
1416 /* To provide backwards compat for apps using mutex incorrectly */
1419 (void)__kdebug_trace(_KSYN_TRACE_UM_UNLOCK
| DBG_FUNC_START
, (uint32_t)mutex
, 0, 0, 0, 0);
1421 if ((sig
!= _PTHREAD_MUTEX_SIG
) && (sig
!= _PTHREAD_MUTEX_SIG_init
)) {
1422 PLOCKSTAT_MUTEX_ERROR(omutex
, EINVAL
);
1425 if (sig
!= _PTHREAD_MUTEX_SIG
) {
1427 if ((sig
!= _PTHREAD_MUTEX_SIG
) && (sig
== _PTHREAD_MUTEX_SIG_init
)) {
1428 /* static initializer, init the mutex */
1429 _new_pthread_mutex_init(omutex
, NULL
);
1430 self
= _PTHREAD_MUTEX_OWNER_SELF
;
1432 UNLOCK(mutex
->lock
);
1433 PLOCKSTAT_MUTEX_ERROR(omutex
, EINVAL
);
1436 UNLOCK(mutex
->lock
);
1439 if (mutex
->mtxopts
.options
.pshared
== PTHREAD_PROCESS_SHARED
) {
1440 MUTEX_GETSEQ_ADDR(mutex
, lseqaddr
, useqaddr
);
1442 lseqaddr
= mutex
->m_lseqaddr
;
1443 useqaddr
= mutex
->m_useqaddr
;
1446 retval
= __mtx_droplock(mutex
, 1, &flags
, NULL
, &mtxgen
, &mtxugen
, ¬ify
);
1450 if ((notify
& 1) != 0) {
1452 (void)__kdebug_trace(_KSYN_TRACE_UM_UNLOCK
| DBG_FUNC_NONE
, (uint32_t)mutex
, 1, 0, 0, 0);
1454 #if USE_COMPAGE /* [ */
1455 if ( __psynch_mutexdrop((pthread_mutex_t
*)lseqaddr
, mtxgen
, mtxugen
, (uint64_t)0, flags
)== (uint32_t)-1)
1456 #else /* USECOMPAGE ][ */
1457 if ( __psynch_mutexdrop(omutex
, mtxgen
, mtxugen
, (uint64_t)0, flags
)== (uint32_t)-1)
1458 #endif /* USE_COMPAGE ] */
1467 (void)__kdebug_trace(_KSYN_TRACE_UM_UNLOCK
| DBG_FUNC_END
, (uint32_t)mutex
, 0, 0, 0, 0);
1474 * Initialize a mutex variable, possibly with additional attributes.
1477 _new_pthread_mutex_init(pthread_mutex_t
*omutex
, const pthread_mutexattr_t
*attr
)
1479 npthread_mutex_t
* mutex
= (npthread_mutex_t
*)omutex
;
1483 if (attr
->sig
!= _PTHREAD_MUTEX_ATTR_SIG
)
1485 mutex
->prioceiling
= attr
->prioceiling
;
1486 mutex
->mtxopts
.options
.protocol
= attr
->protocol
;
1487 mutex
->mtxopts
.options
.policy
= attr
->policy
;
1488 mutex
->mtxopts
.options
.type
= attr
->type
;
1489 mutex
->mtxopts
.options
.pshared
= attr
->pshared
;
1491 mutex
->prioceiling
= _PTHREAD_DEFAULT_PRIOCEILING
;
1492 mutex
->mtxopts
.options
.protocol
= _PTHREAD_DEFAULT_PROTOCOL
;
1493 mutex
->mtxopts
.options
.policy
= _PTHREAD_MUTEX_POLICY_FAIRSHARE
;
1494 mutex
->mtxopts
.options
.type
= PTHREAD_MUTEX_DEFAULT
;
1495 mutex
->mtxopts
.options
.pshared
= _PTHREAD_DEFAULT_PSHARED
;
1498 mutex
->mtxopts
.options
.lock_count
= 0;
1499 /* address 8byte aligned? */
1500 if (((uintptr_t)mutex
& 0x07) != 0) {
1502 mutex
->mtxopts
.options
.misalign
= 1;
1503 #if defined(__LP64__)
1504 mutex
->m_lseqaddr
= &mutex
->m_seq
[0];
1505 mutex
->m_useqaddr
= &mutex
->m_seq
[1];
1506 #else /* __LP64__ */
1507 mutex
->m_lseqaddr
= &mutex
->m_seq
[1];
1508 mutex
->m_useqaddr
= &mutex
->m_seq
[2];
1509 #endif /* __LP64__ */
1512 mutex
->mtxopts
.options
.misalign
= 0;
1513 #if defined(__LP64__)
1514 mutex
->m_lseqaddr
= &mutex
->m_seq
[1];
1515 mutex
->m_useqaddr
= &mutex
->m_seq
[2];
1516 #else /* __LP64__ */
1517 mutex
->m_lseqaddr
= &mutex
->m_seq
[0];
1518 mutex
->m_useqaddr
= &mutex
->m_seq
[1];
1519 #endif /* __LP64__ */
1522 mutex
->m_seq
[0] = 0;
1523 mutex
->m_seq
[1] = 0;
1524 mutex
->m_seq
[2] = 0;
1525 mutex
->prioceiling
= 0;
1526 mutex
->priority
= 0;
1527 mutex
->sig
= _PTHREAD_MUTEX_SIG
;
1534 * Destroy a mutex variable.
1537 _new_pthread_mutex_destroy(pthread_mutex_t
*omutex
)
1540 npthread_mutex_t
* mutex
= (npthread_mutex_t
*)omutex
;
1543 res
= _new_pthread_mutex_destroy_locked(omutex
);
1544 UNLOCK(mutex
->lock
);
1551 _new_pthread_mutex_destroy_locked(pthread_mutex_t
*omutex
)
1554 npthread_mutex_t
* mutex
= (npthread_mutex_t
*)omutex
;
1556 uint32_t * lseqaddr
;
1557 uint32_t * useqaddr
;
1560 if (mutex
->sig
== _PTHREAD_MUTEX_SIG
)
1562 if (mutex
->mtxopts
.options
.pshared
== PTHREAD_PROCESS_SHARED
) {
1563 MUTEX_GETSEQ_ADDR(mutex
, lseqaddr
, useqaddr
);
1565 lseqaddr
= mutex
->m_lseqaddr
;
1566 useqaddr
= mutex
->m_useqaddr
;
1569 lgenval
= *(lseqaddr
);
1570 if ((mutex
->m_tid
== (uint64_t)0) &&
1571 ((lgenval
& PTHRW_COUNT_MASK
) == 0))
1573 mutex
->sig
= _PTHREAD_NO_SIG
;
1584 #endif /* __i386__ || __x86_64__ */
1586 #endif /* !BUILDING_VARIANT ] */
1589 * Destroy a mutex attribute structure.
1592 pthread_mutexattr_destroy(pthread_mutexattr_t
*attr
)
1595 if (__unix_conforming
== 0)
1596 __unix_conforming
= 1;
1597 if (attr
->sig
!= _PTHREAD_MUTEX_ATTR_SIG
)
1599 #endif /* __DARWIN_UNIX03 */
1601 attr
->sig
= _PTHREAD_NO_SIG
; /* Uninitialized */