4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 #include "thr_uberdata.h"
32 * pthread_mutexattr_init: allocates the mutex attribute object and
33 * initializes it with the default values.
35 #pragma weak _pthread_mutexattr_init = pthread_mutexattr_init
37 pthread_mutexattr_init(pthread_mutexattr_t
*attr
)
41 if ((ap
= lmalloc(sizeof (mattr_t
))) == NULL
)
43 ap
->pshared
= PTHREAD_PROCESS_PRIVATE
;
44 ap
->type
= PTHREAD_MUTEX_DEFAULT
;
45 ap
->protocol
= PTHREAD_PRIO_NONE
;
46 ap
->robustness
= PTHREAD_MUTEX_STALLED
;
47 attr
->__pthread_mutexattrp
= ap
;
52 * pthread_mutexattr_destroy: frees the mutex attribute object and
53 * invalidates it with NULL value.
56 pthread_mutexattr_destroy(pthread_mutexattr_t
*attr
)
58 if (attr
== NULL
|| attr
->__pthread_mutexattrp
== NULL
)
60 lfree(attr
->__pthread_mutexattrp
, sizeof (mattr_t
));
61 attr
->__pthread_mutexattrp
= NULL
;
66 * pthread_mutexattr_setpshared: sets the shared attribute
67 * to PTHREAD_PROCESS_PRIVATE or PTHREAD_PROCESS_SHARED.
68 * This is equivalent to setting the USYNC_THREAD/USYNC_PROCESS
69 * flag in mutex_init().
72 pthread_mutexattr_setpshared(pthread_mutexattr_t
*attr
, int pshared
)
76 if (attr
== NULL
|| (ap
= attr
->__pthread_mutexattrp
) == NULL
||
77 (pshared
!= PTHREAD_PROCESS_PRIVATE
&&
78 pshared
!= PTHREAD_PROCESS_SHARED
))
80 ap
->pshared
= pshared
;
85 * pthread_mutexattr_getpshared: gets the shared attribute.
87 #pragma weak _pthread_mutexattr_getpshared = pthread_mutexattr_getpshared
89 pthread_mutexattr_getpshared(const pthread_mutexattr_t
*attr
, int *pshared
)
93 if (attr
== NULL
|| (ap
= attr
->__pthread_mutexattrp
) == NULL
||
96 *pshared
= ap
->pshared
;
101 * pthread_mutexattr_setprioceiling: sets the prioceiling attribute.
104 pthread_mutexattr_setprioceiling(pthread_mutexattr_t
*attr
, int prioceiling
)
106 const pcclass_t
*pccp
= get_info_by_policy(SCHED_FIFO
);
109 if (attr
== NULL
|| (ap
= attr
->__pthread_mutexattrp
) == NULL
||
110 prioceiling
< pccp
->pcc_primin
|| prioceiling
> pccp
->pcc_primax
)
112 ap
->prioceiling
= prioceiling
;
117 * pthread_mutexattr_getprioceiling: gets the prioceiling attribute.
119 #pragma weak _pthread_mutexattr_getprioceiling = \
120 pthread_mutexattr_getprioceiling
122 pthread_mutexattr_getprioceiling(const pthread_mutexattr_t
*attr
, int *ceiling
)
126 if (attr
== NULL
|| (ap
= attr
->__pthread_mutexattrp
) == NULL
||
129 *ceiling
= ap
->prioceiling
;
134 * pthread_mutexattr_setprotocol: sets the protocol attribute.
137 pthread_mutexattr_setprotocol(pthread_mutexattr_t
*attr
, int protocol
)
141 if (attr
== NULL
|| (ap
= attr
->__pthread_mutexattrp
) == NULL
)
143 if (protocol
!= PTHREAD_PRIO_NONE
&&
144 protocol
!= PTHREAD_PRIO_INHERIT
&&
145 protocol
!= PTHREAD_PRIO_PROTECT
)
147 ap
->protocol
= protocol
;
152 * pthread_mutexattr_getprotocol: gets the protocol attribute.
154 #pragma weak _pthread_mutexattr_getprotocol = pthread_mutexattr_getprotocol
156 pthread_mutexattr_getprotocol(const pthread_mutexattr_t
*attr
, int *protocol
)
160 if (attr
== NULL
|| (ap
= attr
->__pthread_mutexattrp
) == NULL
||
163 *protocol
= ap
->protocol
;
168 * pthread_mutexattr_setrobust: set the mutex robust attribute.
169 * pthread_mutexattr_setrobust_np: the historical name.
171 #pragma weak pthread_mutexattr_setrobust_np = pthread_mutexattr_setrobust
173 pthread_mutexattr_setrobust(pthread_mutexattr_t
*attr
, int robust
)
177 if (attr
== NULL
|| (ap
= attr
->__pthread_mutexattrp
) == NULL
||
178 (robust
!= PTHREAD_MUTEX_ROBUST
&& robust
!= PTHREAD_MUTEX_STALLED
))
180 ap
->robustness
= robust
;
185 * pthread_mutexattr_getrobust: get the mutex robust attribute.
186 * pthread_mutexattr_getrobust_np: the historical name.
188 #pragma weak pthread_mutexattr_getrobust_np = pthread_mutexattr_getrobust
190 pthread_mutexattr_getrobust(const pthread_mutexattr_t
*attr
, int *robust
)
194 if (attr
== NULL
|| (ap
= attr
->__pthread_mutexattrp
) == NULL
||
197 *robust
= ap
->robustness
;
202 * pthread_mutex_init: Initializes the mutex object. It copies the
203 * various attributes into one type argument and calls mutex_init().
205 #pragma weak _pthread_mutex_init = pthread_mutex_init
207 pthread_mutex_init(pthread_mutex_t
*_RESTRICT_KYWD mutex
,
208 const pthread_mutexattr_t
*_RESTRICT_KYWD attr
)
215 * All of the pshared, type, protocol, robust attributes
216 * translate to bits in the mutex_type field.
219 if ((ap
= attr
->__pthread_mutexattrp
) == NULL
)
221 type
= ap
->pshared
| ap
->type
| ap
->protocol
| ap
->robustness
;
222 if (ap
->protocol
== PTHREAD_PRIO_PROTECT
)
223 prioceiling
= ap
->prioceiling
;
225 type
= PTHREAD_PROCESS_PRIVATE
| PTHREAD_MUTEX_DEFAULT
|
226 PTHREAD_PRIO_NONE
| PTHREAD_MUTEX_STALLED
;
229 return (mutex_init((mutex_t
*)mutex
, type
, &prioceiling
));
233 * pthread_mutex_setprioceiling: sets the prioceiling.
234 * From the SUSv3 (POSIX) specification for pthread_mutex_setprioceiling():
235 * The process of locking the mutex need not
236 * adhere to the priority protect protocol.
237 * We pass the MUTEX_NOCEIL flag to mutex_lock_internal() so that
238 * a non-realtime thread can successfully execute this operation.
241 pthread_mutex_setprioceiling(pthread_mutex_t
*mutex
, int ceil
, int *oceil
)
243 mutex_t
*mp
= (mutex_t
*)mutex
;
244 const pcclass_t
*pccp
= get_info_by_policy(SCHED_FIFO
);
247 if (!(mp
->mutex_type
& PTHREAD_PRIO_PROTECT
) ||
248 ceil
< pccp
->pcc_primin
|| ceil
> pccp
->pcc_primax
)
250 error
= mutex_lock_internal(mp
, NULL
, MUTEX_LOCK
| MUTEX_NOCEIL
);
251 if (error
== 0 || error
== EOWNERDEAD
|| error
== ELOCKUNMAPPED
) {
253 *oceil
= mp
->mutex_ceiling
;
254 mp
->mutex_ceiling
= ceil
;
255 error
= mutex_unlock_internal(mp
, 1);
261 * pthread_mutex_getprioceiling: gets the prioceiling.
263 #pragma weak _pthread_mutex_getprioceiling = pthread_mutex_getprioceiling
265 pthread_mutex_getprioceiling(const pthread_mutex_t
*mp
, int *ceiling
)
267 *ceiling
= ((mutex_t
*)mp
)->mutex_ceiling
;
273 * pthread_mutexattr_settype: sets the type attribute
276 pthread_mutexattr_settype(pthread_mutexattr_t
*attr
, int type
)
280 if (attr
== NULL
|| (ap
= attr
->__pthread_mutexattrp
) == NULL
)
283 case PTHREAD_MUTEX_NORMAL
:
286 case PTHREAD_MUTEX_ERRORCHECK
:
287 type
= LOCK_ERRORCHECK
;
289 case PTHREAD_MUTEX_RECURSIVE
:
290 type
= LOCK_RECURSIVE
| LOCK_ERRORCHECK
;
301 * pthread_mutexattr_gettype: gets the type attribute.
304 pthread_mutexattr_gettype(const pthread_mutexattr_t
*attr
, int *typep
)
309 if (attr
== NULL
|| (ap
= attr
->__pthread_mutexattrp
) == NULL
||
314 type
= PTHREAD_MUTEX_NORMAL
;
316 case LOCK_ERRORCHECK
:
317 type
= PTHREAD_MUTEX_ERRORCHECK
;
319 case LOCK_RECURSIVE
| LOCK_ERRORCHECK
:
320 type
= PTHREAD_MUTEX_RECURSIVE
;