209 {
210 mattr_t *ap;
211 int type;
212 int prioceiling = 0;
213
214 /*
215 * All of the pshared, type, protocol, robust attributes
216 * translate to bits in the mutex_type field.
217 */
218 if (attr != NULL) {
219 if ((ap = attr->__pthread_mutexattrp) == NULL)
220 return (EINVAL);
221 type = ap->pshared | ap->type | ap->protocol | ap->robustness;
222 if (ap->protocol == PTHREAD_PRIO_PROTECT)
223 prioceiling = ap->prioceiling;
224 } else {
225 type = PTHREAD_PROCESS_PRIVATE | PTHREAD_MUTEX_DEFAULT |
226 PTHREAD_PRIO_NONE | PTHREAD_MUTEX_STALLED;
227 }
228
229 return (mutex_init((mutex_t *)mutex, type, &prioceiling));
230 }
231
232 /*
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.
239 */
240 int
241 pthread_mutex_setprioceiling(pthread_mutex_t *mutex, int ceil, int *oceil)
242 {
243 mutex_t *mp = (mutex_t *)mutex;
244 const pcclass_t *pccp = get_info_by_policy(SCHED_FIFO);
245 int error;
246
247 if (!(mp->mutex_type & PTHREAD_PRIO_PROTECT) ||
248 ceil < pccp->pcc_primin || ceil > pccp->pcc_primax)
|
209 {
210 mattr_t *ap;
211 int type;
212 int prioceiling = 0;
213
214 /*
215 * All of the pshared, type, protocol, robust attributes
216 * translate to bits in the mutex_type field.
217 */
218 if (attr != NULL) {
219 if ((ap = attr->__pthread_mutexattrp) == NULL)
220 return (EINVAL);
221 type = ap->pshared | ap->type | ap->protocol | ap->robustness;
222 if (ap->protocol == PTHREAD_PRIO_PROTECT)
223 prioceiling = ap->prioceiling;
224 } else {
225 type = PTHREAD_PROCESS_PRIVATE | PTHREAD_MUTEX_DEFAULT |
226 PTHREAD_PRIO_NONE | PTHREAD_MUTEX_STALLED;
227 }
228
229 /*
230 * POSIX mutexes (this interface) make no guarantee about the state of
231 * the mutex before pthread_mutex_init(3C) is called. Sun mutexes, upon
232 * which these are built and which mutex_init(3C) below represents
233 * require that a robust mutex be initialized to all 0s _prior_ to
234 * mutex_init() being called, and that mutex_init() of an initialized
235 * mutex return EBUSY.
236 *
237 * We respect both these behaviors by zeroing the mutex here in the
238 * POSIX implementation if and only if the mutex magic is incorrect,
239 * and the mutex is robust.
240 */
241 if (((type & PTHREAD_MUTEX_ROBUST) != 0) &&
242 (((mutex_t *)mutex)->mutex_magic != MUTEX_MAGIC)) {
243 (void) memset(mutex, 0, sizeof (*mutex));
244 }
245
246 return (mutex_init((mutex_t *)mutex, type, &prioceiling));
247 }
248
249 /*
250 * pthread_mutex_setprioceiling: sets the prioceiling.
251 * From the SUSv3 (POSIX) specification for pthread_mutex_setprioceiling():
252 * The process of locking the mutex need not
253 * adhere to the priority protect protocol.
254 * We pass the MUTEX_NOCEIL flag to mutex_lock_internal() so that
255 * a non-realtime thread can successfully execute this operation.
256 */
257 int
258 pthread_mutex_setprioceiling(pthread_mutex_t *mutex, int ceil, int *oceil)
259 {
260 mutex_t *mp = (mutex_t *)mutex;
261 const pcclass_t *pccp = get_info_by_policy(SCHED_FIFO);
262 int error;
263
264 if (!(mp->mutex_type & PTHREAD_PRIO_PROTECT) ||
265 ceil < pccp->pcc_primin || ceil > pccp->pcc_primax)
|