void threadSleep(Thread *self, long long ms, int ns) { /* A sleep of zero should just yield, but a wait of zero is "forever". Therefore wait for a tiny amount -- this should yield and we also get the interrupted checks. */ if(ms == 0 && ns == 0) ns = 1; monitorLock(&sleep_mon, self); monitorWait(&sleep_mon, self, ms, ns); monitorUnlock(&sleep_mon, self); }
void Java_java_lang_Object_wait(void) { long64 period; OBJECT object; popLong(period); object = popStackAsType(OBJECT); /* only block if the time period is not zero */ if (ll_zero_ge(period)) { monitorWait(object, period); } else { raiseException("java/lang/IllegalArgumentException"); } }
void objectLock(Object *obj) { Thread *self = threadSelf(); uintptr_t thin_locked = self->id<<TID_SHIFT; uintptr_t entering, lockword; Monitor *mon; TRACE("Thread %p lock on obj %p...\n", self, obj); if(LOCKWORD_COMPARE_AND_SWAP(&obj->lock, 0, thin_locked)) { /* This barrier is not needed for the thin-locking implementation; it's a requirement of the Java memory model. */ JMM_LOCK_MBARRIER(); return; } lockword = LOCKWORD_READ(&obj->lock); if((lockword & (TID_MASK|SHAPE_BIT)) == thin_locked) { int count = lockword & COUNT_MASK; if(count < (((1<<COUNT_SIZE)-1)<<COUNT_SHIFT)) LOCKWORD_WRITE(&obj->lock, lockword + (1<<COUNT_SHIFT)); else { mon = findMonitor(obj); monitorLock(mon, self); inflate(obj, mon, self); mon->count = 1<<COUNT_SIZE; } return; } try_again: mon = findMonitor(obj); try_again2: if((entering = LOCKWORD_READ(&mon->entering)) == UN_USED) goto try_again; if(!(LOCKWORD_COMPARE_AND_SWAP(&mon->entering, entering, entering+1))) goto try_again2; if(mon->obj != obj) { while(entering = LOCKWORD_READ(&mon->entering), !(LOCKWORD_COMPARE_AND_SWAP(&mon->entering, entering, entering-1))); goto try_again; } monitorLock(mon, self); while(entering = LOCKWORD_READ(&mon->entering), !(LOCKWORD_COMPARE_AND_SWAP(&mon->entering, entering, entering-1))); while((LOCKWORD_READ(&obj->lock) & SHAPE_BIT) == 0) { setFlcBit(obj); if(LOCKWORD_COMPARE_AND_SWAP(&obj->lock, 0, thin_locked)) inflate(obj, mon, self); else monitorWait(mon, self, 0, 0, FALSE, FALSE); } }