void CVMthreadBoostAndWait(CVMThreadID *self, CVMThreadBoostRecord *bp, CVMThreadBoostQueue *b) { CVMBool destroy = CVM_FALSE; assert(b->nboosters > 0); #ifdef SOLARIS_BOOST_MUTEX { SOLARISBoostLock *l = b->thread_lock; do { mutex_lock(&l->lock); mutex_unlock(&l->lock); } while (b->boosting); } #else sem_wait(&b->sem); #endif assert(!b->boosting); mutex_lock(&b->lock); assert(b->nboosters > 0); assert((b->nboosters == 0) == (b->boosters.waiters == NULL)); --b->nboosters; dequeue_me(&b->boosters, self); assert((b->nboosters == 0) == (b->boosters.waiters == NULL)); /* Last to wakeup should have a missing boost record */ assert(b->boosters.waiters != NULL || self->boost == NULL); if (self->boost == NULL) { /* I need my record back */ if (b->boosters.waiters != NULL) { /* Steal one */ self->boost = b->boosters.waiters->boost; b->boosters.waiters->boost = NULL; assert(self->boost != NULL); } else { self->boost = b; } } assert(!b->boosting); if (b->nboosters == 0) { destroy = CVM_TRUE; } mutex_unlock(&b->lock); if (destroy) { if (b->thread_lock != NULL) { boostLockRemoveReference(b); } } }
int sysMonitorWait(sys_thread_t *self, sys_mon_t *mid, jlong millis) { int ret = SYS_OK; monitor_waiter_t me; sysAssert(mid != SYS_MID_NULL); if (self != mid->monitor_owner) { return SYS_ERR; } if (sysThreadIsInterrupted(self, TRUE)) { return SYS_INTRPT; } /* Prepare to wait: drop mutex ownership */ sysAssert(self->monitor_entry_count == 0); sysAssert(self->mon_wait == 0); self->mon_wait = (sys_mon_t *) mid; self->monitor_entry_count = mid->entry_count; mid->entry_count = 0; mid->monitor_owner = SYS_THREAD_NULL; /* Add myself to the monitor waitq */ enqueue_me(&me, &mid->mwait_queue, self); if (millis == SYS_TIMEOUT_INFINITY) { ret = condvarWait(&mid->cv_monitor, &mid->mutex, CONDVAR_WAIT); } else { ret = condvarTimedWait(&mid->cv_monitor, &mid->mutex, millis, CONDVAR_WAIT); } dequeue_me(&me, &mid->mwait_queue); sysAssert(mid->monitor_owner == NULL); sysAssert(mid->entry_count == 0); mid->monitor_owner = self; mid->entry_count = self->monitor_entry_count; self->monitor_entry_count = 0; self->mon_wait = 0; /* Did we get interrupted in mid-wait? (IS THIS THE RIGHT PLACE?) */ if (sysThreadIsInterrupted(self, TRUE)) { return SYS_INTRPT; } return ret; }