+ thread_t thread, self = current_thread();
+#if !defined(i386)
+ integer_t priority;
+ spl_t s = splsched();
+
+ priority = self->last_processor->current_pri;
+ if (priority < self->priority)
+ priority = self->priority;
+ if (priority > MINPRI_KERNEL)
+ priority = MINPRI_KERNEL;
+ else
+ if (priority < BASEPRI_DEFAULT)
+ priority = BASEPRI_DEFAULT;
+
+ thread = holder->thread;
+ assert(thread->top_act == holder); /* XXX */
+ thread_lock(thread);
+ if (mutex->promoted_pri == 0)
+ thread->promotions++;
+ if (thread->priority < MINPRI_KERNEL) {
+ thread->sched_mode |= TH_MODE_PROMOTED;
+ if ( mutex->promoted_pri < priority &&
+ thread->sched_pri < priority ) {
+ KERNEL_DEBUG_CONSTANT(
+ MACHDBG_CODE(DBG_MACH_SCHED,MACH_PROMOTE) | DBG_FUNC_NONE,
+ thread->sched_pri, priority, (int)thread, (int)mutex, 0);
+
+ set_sched_pri(thread, priority);
+ }
+ }
+ thread_unlock(thread);
+ splx(s);
+
+ if (mutex->promoted_pri < priority)
+ mutex->promoted_pri = priority;
+#endif
+
+ if (self->pending_promoter[self->pending_promoter_index] == NULL) {
+ self->pending_promoter[self->pending_promoter_index] = mutex;
+ mutex->waiters++;
+ }
+ else
+ if (self->pending_promoter[self->pending_promoter_index] != mutex) {
+ self->pending_promoter[++self->pending_promoter_index] = mutex;
+ mutex->waiters++;
+ }
+
+ assert_wait(mutex, THREAD_UNINT);
+ interlock_unlock(&mutex->interlock);
+
+ thread_block(THREAD_CONTINUE_NULL);