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);
	}
    }
}
Exemple #2
0
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;
}