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
; 
  69 #ifndef BUILDING_VARIANT /* [ */ 
  71 #define BLOCK_FAIL_PLOCKSTAT    0 
  72 #define BLOCK_SUCCESS_PLOCKSTAT 1 
  74 /* This function is never called and exists to provide never-fired dtrace 
  75  * probes so that user d scripts don't get errors. 
  77 __private_extern__ 
void _plockstat_never_fired(void)  
  79         PLOCKSTAT_MUTEX_SPIN(NULL
); 
  80         PLOCKSTAT_MUTEX_SPUN(NULL
, 0, 0); 
  84  * Destroy a mutex variable. 
  87 pthread_mutex_destroy(pthread_mutex_t 
*mutex
) 
  92         if (mutex
->sig 
== _PTHREAD_MUTEX_SIG
) 
  94                 if (mutex
->owner 
== (pthread_t
)NULL 
&& 
  95                     mutex
->busy 
== (pthread_cond_t 
*)NULL
) 
  97                         mutex
->sig 
= _PTHREAD_NO_SIG
; 
 102         } else if (mutex
->sig  
== _PTHREAD_KERN_MUTEX_SIG
) { 
 103                                 int mutexid 
= mutex
->_pthread_mutex_kernid
; 
 105                                 if( __pthread_mutex_destroy(mutexid
) == -1) 
 107                                 mutex
->sig 
= _PTHREAD_NO_SIG
;    
 116 /* 5243343 - temporary hack to detect if we are running the conformance test */ 
 117 extern int PR_5243343_flag
; 
 118 #endif /* PR_5243343 */ 
 120  * Initialize a mutex variable, possibly with additional attributes. 
 123 _pthread_mutex_init(pthread_mutex_t 
*mutex
, const pthread_mutexattr_t 
*attr
) 
 127                 if (attr
->sig 
!= _PTHREAD_MUTEX_ATTR_SIG
) 
 129                 mutex
->prioceiling 
= attr
->prioceiling
; 
 130                 mutex
->protocol 
= attr
->protocol
; 
 131                 mutex
->type 
= attr
->type
; 
 132                 mutex
->pshared 
= attr
->pshared
; 
 133                 if (attr
->pshared 
== PTHREAD_PROCESS_SHARED
) { 
 134                         mutex
->lock_count 
= 0; 
 135                         mutex
->owner 
= (pthread_t
)NULL
; 
 136                         mutex
->next 
= (pthread_mutex_t 
*)NULL
; 
 137                         mutex
->prev 
= (pthread_mutex_t 
*)NULL
; 
 138                         mutex
->busy 
= (pthread_cond_t 
*)NULL
; 
 140                         mutex
->sem 
= SEMAPHORE_NULL
; 
 141                         mutex
->order 
= SEMAPHORE_NULL
; 
 143                         if( __pthread_mutex_init(mutex
, attr
) == -1) 
 145                         mutex
->sig 
= _PTHREAD_KERN_MUTEX_SIG
; 
 149                 mutex
->prioceiling 
= _PTHREAD_DEFAULT_PRIOCEILING
; 
 150                 mutex
->protocol 
= _PTHREAD_DEFAULT_PROTOCOL
; 
 151                 mutex
->type 
= PTHREAD_MUTEX_DEFAULT
; 
 152                 mutex
->pshared 
= _PTHREAD_DEFAULT_PSHARED
; 
 154         mutex
->lock_count 
= 0; 
 155         mutex
->owner 
= (pthread_t
)NULL
; 
 156         mutex
->next 
= (pthread_mutex_t 
*)NULL
; 
 157         mutex
->prev 
= (pthread_mutex_t 
*)NULL
; 
 158         mutex
->busy 
= (pthread_cond_t 
*)NULL
; 
 160         mutex
->sem 
= SEMAPHORE_NULL
; 
 161         mutex
->order 
= SEMAPHORE_NULL
; 
 162         mutex
->sig 
= _PTHREAD_MUTEX_SIG
; 
 167  * Initialize a mutex variable, possibly with additional attributes. 
 168  * Public interface - so don't trust the lock - initialize it first. 
 171 pthread_mutex_init(pthread_mutex_t 
*mutex
, const pthread_mutexattr_t 
*attr
) 
 174         /* conformance tests depend on not having this behavior */ 
 175         /* The test for this behavior is optional */ 
 176         if (mutex
->sig 
== _PTHREAD_MUTEX_SIG
) 
 179         LOCK_INIT(mutex
->lock
); 
 180         return (_pthread_mutex_init(mutex
, attr
)); 
 184  * Manage a list of mutex variables owned by a thread 
 188 _pthread_mutex_add(pthread_mutex_t 
*mutex
, pthread_t self
) 
 191         if (self 
!= (pthread_t
)0) 
 193                 if ((m 
= self
->mutexes
) != (pthread_mutex_t 
*)NULL
) 
 198                 mutex
->prev 
= (pthread_mutex_t 
*)NULL
; 
 199                 self
->mutexes 
= mutex
; 
 203 __private_extern__ 
void 
 204 _pthread_mutex_remove(pthread_mutex_t 
*mutex
, pthread_t self
) 
 206         pthread_mutex_t 
*n
, *prev
; 
 207         if ((n 
= mutex
->next
) != (pthread_mutex_t 
*)NULL
) 
 209                 n
->prev 
= mutex
->prev
; 
 211         if ((prev 
= mutex
->prev
) != (pthread_mutex_t 
*)NULL
) 
 213                 prev
->next 
= mutex
->next
; 
 215         { /* This is the first in the list */ 
 216                 if (self 
!= (pthread_t
)0) { 
 225  * TODO: Priority inheritance stuff 
 228 pthread_mutex_lock(pthread_mutex_t 
*mutex
) 
 230         kern_return_t kern_res
; 
 232         int sig 
= mutex
->sig
;  
 234         /* To provide backwards compat for apps using mutex incorrectly */ 
 235         if ((sig 
!= _PTHREAD_MUTEX_SIG
) && (sig 
!= _PTHREAD_MUTEX_SIG_init
) && (sig 
!= _PTHREAD_KERN_MUTEX_SIG
)) { 
 236                 PLOCKSTAT_MUTEX_ERROR(mutex
, EINVAL
); 
 240         if (mutex
->sig 
!= _PTHREAD_MUTEX_SIG
) 
 242                 if (mutex
->sig 
!= _PTHREAD_MUTEX_SIG_init
) 
 244                         if (mutex
->sig  
== _PTHREAD_KERN_MUTEX_SIG
) { 
 245                                 int mutexid 
= mutex
->_pthread_mutex_kernid
; 
 248                                 PLOCKSTAT_MUTEX_BLOCK(mutex
); 
 249                                 if( __pthread_mutex_lock(mutexid
) == -1) { 
 250                                         PLOCKSTAT_MUTEX_BLOCKED(mutex
, BLOCK_FAIL_PLOCKSTAT
); 
 251                                         PLOCKSTAT_MUTEX_ERROR(mutex
, errno
); 
 255                                 PLOCKSTAT_MUTEX_BLOCKED(mutex
, BLOCK_SUCCESS_PLOCKSTAT
); 
 256                                 PLOCKSTAT_MUTEX_ACQUIRE(mutex
, 0, 0); 
 260                                 PLOCKSTAT_MUTEX_ERROR(mutex
, EINVAL
); 
 264                 _pthread_mutex_init(mutex
, NULL
); 
 265                 self 
= _PTHREAD_MUTEX_OWNER_SELF
; 
 267         else if (mutex
->type 
!= PTHREAD_MUTEX_NORMAL
) 
 269                 self 
= pthread_self(); 
 270                 if (mutex
->owner 
== self
) 
 274                         if (mutex
->type 
== PTHREAD_MUTEX_RECURSIVE
) 
 276                                 if (mutex
->lock_count 
< USHRT_MAX
) 
 279                                         PLOCKSTAT_MUTEX_ACQUIRE(mutex
, 1, 0); 
 283                                         PLOCKSTAT_MUTEX_ERROR(mutex
, res
); 
 285                         } else  { /* PTHREAD_MUTEX_ERRORCHECK */ 
 287                                 PLOCKSTAT_MUTEX_ERROR(mutex
, res
); 
 293                 self 
= _PTHREAD_MUTEX_OWNER_SELF
; 
 295         if (mutex
->owner 
!= (pthread_t
)NULL
) { 
 296                 if (mutex
->waiters 
|| mutex
->owner 
!= _PTHREAD_MUTEX_OWNER_SWITCHING
) 
 298                         semaphore_t sem
, order
; 
 300                         if (++mutex
->waiters 
== 1) 
 302                                 mutex
->sem 
= sem 
= new_sem_from_pool(); 
 303                                 mutex
->order 
= order 
= new_sem_from_pool(); 
 308                                 order 
= mutex
->order
; 
 310                                         PTHREAD_MACH_CALL(semaphore_wait(order
), kern_res
); 
 311                                 } while (kern_res 
== KERN_ABORTED
); 
 315                         PLOCKSTAT_MUTEX_BLOCK(mutex
); 
 316                         PTHREAD_MACH_CALL(semaphore_wait_signal(sem
, order
), kern_res
); 
 317                         while (kern_res 
== KERN_ABORTED
) 
 319                                 PTHREAD_MACH_CALL(semaphore_wait(sem
), kern_res
); 
 322                         PLOCKSTAT_MUTEX_BLOCKED(mutex
, BLOCK_SUCCESS_PLOCKSTAT
); 
 325                         if (--mutex
->waiters 
== 0) 
 327                                 PTHREAD_MACH_CALL(semaphore_wait(order
), kern_res
); 
 328                                 mutex
->sem 
= mutex
->order 
= SEMAPHORE_NULL
; 
 329                                 restore_sem_to_pool(order
); 
 330                                 restore_sem_to_pool(sem
); 
 333                 else if (mutex
->owner 
== _PTHREAD_MUTEX_OWNER_SWITCHING
) 
 335                         semaphore_t sem 
= mutex
->sem
; 
 337                                 PTHREAD_MACH_CALL(semaphore_wait(sem
), kern_res
); 
 338                         } while (kern_res 
== KERN_ABORTED
); 
 339                         mutex
->sem 
= SEMAPHORE_NULL
; 
 340                         restore_sem_to_pool(sem
); 
 344         mutex
->lock_count 
= 1; 
 347         _pthread_mutex_add(mutex
, self
); 
 350         PLOCKSTAT_MUTEX_ACQUIRE(mutex
, 0, 0); 
 355  * Attempt to lock a mutex, but don't block if this isn't possible. 
 358 pthread_mutex_trylock(pthread_mutex_t 
*mutex
) 
 360         kern_return_t kern_res
; 
 364         if (mutex
->sig 
!= _PTHREAD_MUTEX_SIG
) 
 366                 if (mutex
->sig 
!= _PTHREAD_MUTEX_SIG_init
) 
 369                         if (mutex
->sig  
== _PTHREAD_KERN_MUTEX_SIG
) { 
 370                                 int mutexid 
= mutex
->_pthread_mutex_kernid
; 
 372                                 if( __pthread_mutex_trylock(mutexid
) == -1) { 
 373                                         PLOCKSTAT_MUTEX_ERROR(mutex
, errno
); 
 376                                 PLOCKSTAT_MUTEX_ACQUIRE(mutex
, 0, 0); 
 379                                 PLOCKSTAT_MUTEX_ERROR(mutex
, EINVAL
); 
 384                 _pthread_mutex_init(mutex
, NULL
); 
 385                 self 
= _PTHREAD_MUTEX_OWNER_SELF
; 
 387         else if (mutex
->type 
!= PTHREAD_MUTEX_NORMAL
) 
 389                 self 
= pthread_self(); 
 390                 if (mutex
->type 
== PTHREAD_MUTEX_RECURSIVE
) 
 392                         if (mutex
->owner 
== self
) 
 396                                 if (mutex
->lock_count 
< USHRT_MAX
) 
 399                                         PLOCKSTAT_MUTEX_ACQUIRE(mutex
, 1, 0); 
 403                                         PLOCKSTAT_MUTEX_ERROR(mutex
, res
); 
 410                 self 
= _PTHREAD_MUTEX_OWNER_SELF
; 
 412         if (mutex
->owner 
!= (pthread_t
)NULL
) 
 414                 if (mutex
->waiters 
|| mutex
->owner 
!= _PTHREAD_MUTEX_OWNER_SWITCHING
) 
 416                         PLOCKSTAT_MUTEX_ERROR(mutex
, EBUSY
); 
 420                 else if (mutex
->owner 
== _PTHREAD_MUTEX_OWNER_SWITCHING
) 
 422                         semaphore_t sem 
= mutex
->sem
; 
 425                                 PTHREAD_MACH_CALL(semaphore_wait(sem
), kern_res
); 
 426                         } while (kern_res 
== KERN_ABORTED
); 
 427                         restore_sem_to_pool(sem
); 
 428                         mutex
->sem 
= SEMAPHORE_NULL
; 
 432         mutex
->lock_count 
= 1; 
 435         _pthread_mutex_add(mutex
, self
); 
 438         PLOCKSTAT_MUTEX_ACQUIRE(mutex
, 0, 0); 
 444  * TODO: Priority inheritance stuff 
 447 pthread_mutex_unlock(pthread_mutex_t 
*mutex
) 
 449         kern_return_t kern_res
; 
 451         int sig 
= mutex
->sig
;  
 453         /* To provide backwards compat for apps using mutex incorrectly */ 
 455         if ((sig 
!= _PTHREAD_MUTEX_SIG
) && (sig 
!= _PTHREAD_MUTEX_SIG_init
) && (sig 
!= _PTHREAD_KERN_MUTEX_SIG
)) { 
 456                 PLOCKSTAT_MUTEX_ERROR(mutex
, EINVAL
); 
 460         if (mutex
->sig 
!= _PTHREAD_MUTEX_SIG
) 
 462                 if (mutex
->sig 
!= _PTHREAD_MUTEX_SIG_init
) 
 464                         if (mutex
->sig  
== _PTHREAD_KERN_MUTEX_SIG
) { 
 465                                 int mutexid 
= mutex
->_pthread_mutex_kernid
; 
 467                                 if( __pthread_mutex_unlock(mutexid
) == -1) { 
 468                                         PLOCKSTAT_MUTEX_ERROR(mutex
, errno
); 
 471                                 PLOCKSTAT_MUTEX_RELEASE(mutex
, 0); 
 474                                 PLOCKSTAT_MUTEX_ERROR(mutex
, EINVAL
); 
 479                 _pthread_mutex_init(mutex
, NULL
); 
 483         if (mutex
->type 
!= PTHREAD_MUTEX_NORMAL
) 
 486                 pthread_t self 
= pthread_self(); 
 487                 if (mutex
->owner 
!= self
) 
 492                         PLOCKSTAT_MUTEX_ERROR(mutex
, EPERM
); 
 495                 } else if (mutex
->type 
== PTHREAD_MUTEX_RECURSIVE 
&& 
 498                         PLOCKSTAT_MUTEX_RELEASE(mutex
, 1); 
 504         mutex
->lock_count 
= 0; 
 506         _pthread_mutex_remove(mutex
, mutex
->owner
); 
 509         waiters 
= mutex
->waiters
; 
 512                 mutex
->owner 
= _PTHREAD_MUTEX_OWNER_SWITCHING
; 
 513                 PLOCKSTAT_MUTEX_RELEASE(mutex
, 0); 
 515                 PTHREAD_MACH_CALL(semaphore_signal(mutex
->sem
), kern_res
); 
 519                 mutex
->owner 
= (pthread_t
)NULL
; 
 520                 PLOCKSTAT_MUTEX_RELEASE(mutex
, 0); 
 527  * Fetch the priority ceiling value from a mutex variable. 
 528  * Note: written as a 'helper' function to hide implementation details. 
 531 pthread_mutex_getprioceiling(const pthread_mutex_t 
*mutex
, 
 537         if (mutex
->sig 
== _PTHREAD_MUTEX_SIG
) 
 539                 *prioceiling 
= mutex
->prioceiling
; 
 542                 res 
= EINVAL
; /* Not an initialized 'attribute' structure */ 
 548  * Set the priority ceiling for a mutex. 
 549  * Note: written as a 'helper' function to hide implementation details. 
 552 pthread_mutex_setprioceiling(pthread_mutex_t 
*mutex
, 
 554                              int *old_prioceiling
) 
 559         if (mutex
->sig 
== _PTHREAD_MUTEX_SIG
) 
 561                 if ((prioceiling 
>= -999) || 
 562                     (prioceiling 
<= 999)) 
 564                         *old_prioceiling 
= mutex
->prioceiling
; 
 565                         mutex
->prioceiling 
= prioceiling
; 
 568                         res 
= EINVAL
; /* Invalid parameter */ 
 570                 res 
= EINVAL
; /* Not an initialized 'attribute' structure */ 
 576  * Get the priority ceiling value from a mutex attribute structure. 
 577  * Note: written as a 'helper' function to hide implementation details. 
 580 pthread_mutexattr_getprioceiling(const pthread_mutexattr_t 
*attr
, 
 583         if (attr
->sig 
== _PTHREAD_MUTEX_ATTR_SIG
) 
 585                 *prioceiling 
= attr
->prioceiling
; 
 589                 return (EINVAL
); /* Not an initialized 'attribute' structure */ 
 594  * Get the mutex 'protocol' value from a mutex attribute structure. 
 595  * Note: written as a 'helper' function to hide implementation details. 
 598 pthread_mutexattr_getprotocol(const pthread_mutexattr_t 
*attr
, 
 601         if (attr
->sig 
== _PTHREAD_MUTEX_ATTR_SIG
) 
 603                 *protocol 
= attr
->protocol
; 
 607                 return (EINVAL
); /* Not an initialized 'attribute' structure */ 
 611  * Get the mutex 'type' value from a mutex attribute structure. 
 612  * Note: written as a 'helper' function to hide implementation details. 
 615 pthread_mutexattr_gettype(const pthread_mutexattr_t 
*attr
, 
 618         if (attr
->sig 
== _PTHREAD_MUTEX_ATTR_SIG
) 
 624                 return (EINVAL
); /* Not an initialized 'attribute' structure */ 
 632 pthread_mutexattr_getpshared(const pthread_mutexattr_t 
*attr
, int *pshared
) 
 634         if (attr
->sig 
== _PTHREAD_MUTEX_ATTR_SIG
) 
 636                 *pshared 
= (int)attr
->pshared
; 
 640                 return (EINVAL
); /* Not an initialized 'attribute' structure */ 
 645  * Initialize a mutex attribute structure to system defaults. 
 648 pthread_mutexattr_init(pthread_mutexattr_t 
*attr
) 
 650         attr
->prioceiling 
= _PTHREAD_DEFAULT_PRIOCEILING
; 
 651         attr
->protocol 
= _PTHREAD_DEFAULT_PROTOCOL
; 
 652         attr
->type 
= PTHREAD_MUTEX_DEFAULT
; 
 653         attr
->sig 
= _PTHREAD_MUTEX_ATTR_SIG
; 
 654         attr
->pshared 
= _PTHREAD_DEFAULT_PSHARED
; 
 659  * Set the priority ceiling value in a mutex attribute structure. 
 660  * Note: written as a 'helper' function to hide implementation details. 
 663 pthread_mutexattr_setprioceiling(pthread_mutexattr_t 
*attr
, 
 666         if (attr
->sig 
== _PTHREAD_MUTEX_ATTR_SIG
) 
 668                 if ((prioceiling 
>= -999) || 
 669                     (prioceiling 
<= 999)) 
 671                         attr
->prioceiling 
= prioceiling
; 
 675                         return (EINVAL
); /* Invalid parameter */ 
 679                 return (EINVAL
); /* Not an initialized 'attribute' structure */ 
 684  * Set the mutex 'protocol' value in a mutex attribute structure. 
 685  * Note: written as a 'helper' function to hide implementation details. 
 688 pthread_mutexattr_setprotocol(pthread_mutexattr_t 
*attr
, 
 691         if (attr
->sig 
== _PTHREAD_MUTEX_ATTR_SIG
) 
 693                 if ((protocol 
== PTHREAD_PRIO_NONE
) || 
 694                     (protocol 
== PTHREAD_PRIO_INHERIT
) || 
 695                     (protocol 
== PTHREAD_PRIO_PROTECT
)) 
 697                         attr
->protocol 
= protocol
; 
 701                         return (EINVAL
); /* Invalid parameter */ 
 705                 return (EINVAL
); /* Not an initialized 'attribute' structure */ 
 709  * Set the mutex 'type' value in a mutex attribute structure. 
 710  * Note: written as a 'helper' function to hide implementation details. 
 713 pthread_mutexattr_settype(pthread_mutexattr_t 
*attr
, 
 716         if (attr
->sig 
== _PTHREAD_MUTEX_ATTR_SIG
) 
 718                 if ((type 
== PTHREAD_MUTEX_NORMAL
) || 
 719                     (type 
== PTHREAD_MUTEX_ERRORCHECK
) || 
 720                     (type 
== PTHREAD_MUTEX_RECURSIVE
) || 
 721                     (type 
== PTHREAD_MUTEX_DEFAULT
)) 
 727                         return (EINVAL
); /* Invalid parameter */ 
 731                 return (EINVAL
); /* Not an initialized 'attribute' structure */ 
 736 int mutex_try_lock(int *x
) { 
 737         return _spin_lock_try((pthread_lock_t 
*)x
); 
 740 void mutex_wait_lock(int *x
) { 
 742                 if( _spin_lock_try((pthread_lock_t 
*)x
)) { 
 756 pthread_yield_np (void)  
 763  * Temp: till pshared is fixed correctly 
 766 pthread_mutexattr_setpshared(pthread_mutexattr_t 
*attr
, int pshared
) 
 769         if (__unix_conforming 
== 0) 
 770                 __unix_conforming 
= 1; 
 771 #endif /* __DARWIN_UNIX03 */ 
 773         if (attr
->sig 
== _PTHREAD_MUTEX_ATTR_SIG
) 
 777                 if (( pshared 
== PTHREAD_PROCESS_PRIVATE
) || (pshared 
== PTHREAD_PROCESS_SHARED 
&& PR_5243343_flag
)) 
 778 #else /* !PR_5243343 */ 
 779                 if (( pshared 
== PTHREAD_PROCESS_PRIVATE
) || (pshared 
== PTHREAD_PROCESS_SHARED
)) 
 780 #endif /* PR_5243343 */ 
 781 #else /* __DARWIN_UNIX03 */ 
 782                 if ( pshared 
== PTHREAD_PROCESS_PRIVATE
) 
 783 #endif /* __DARWIN_UNIX03 */ 
 785                          attr
->pshared 
= pshared
;  
 789                         return (EINVAL
); /* Invalid parameter */ 
 793                 return (EINVAL
); /* Not an initialized 'attribute' structure */ 
 798 #endif /* !BUILDING_VARIANT ] */ 
 801  * Destroy a mutex attribute structure. 
 804 pthread_mutexattr_destroy(pthread_mutexattr_t 
*attr
) 
 807         if (__unix_conforming 
== 0) 
 808                 __unix_conforming 
= 1; 
 809         if (attr
->sig 
!= _PTHREAD_MUTEX_ATTR_SIG
) 
 811 #endif /* __DARWIN_UNIX03 */ 
 813         attr
->sig 
= _PTHREAD_NO_SIG
;  /* Uninitialized */