void objectUnlock(Object *obj) { Thread *self = threadSelf(); uintptr_t lockword = LOCKWORD_READ(&obj->lock); uintptr_t thin_locked = self->id<<TID_SHIFT; TRACE("Thread %p unlock on obj %p...\n", self, obj); if(lockword == thin_locked) { /* This barrier is not needed for the thin-locking implementation; it's a requirement of the Java memory model. */ JMM_UNLOCK_MBARRIER(); LOCKWORD_WRITE(&obj->lock, 0); /* Required by thin-locking mechanism. */ MBARRIER(); retry: if(testFlcBit(obj)) { Monitor *mon = findMonitor(obj); if(!monitorTryLock(mon, self)) { threadYield(self); goto retry; } if(testFlcBit(obj) && (mon->obj == obj)) monitorNotify(mon, self); monitorUnlock(mon, self); } } else { if((lockword & (TID_MASK|SHAPE_BIT)) == thin_locked) LOCKWORD_WRITE(&obj->lock, lockword - (1<<COUNT_SHIFT)); else if((lockword & SHAPE_BIT) != 0) { Monitor *mon = (Monitor*) (lockword & ~SHAPE_BIT); if((mon->count == 0) && (LOCKWORD_READ(&mon->entering) == 0) && (mon->in_wait == 0)) { TRACE("Thread %p is deflating obj %p...\n", self, obj); /* This barrier is not needed for the thin-locking implementation; it's a requirement of the Java memory model. */ JMM_UNLOCK_MBARRIER(); LOCKWORD_WRITE(&obj->lock, 0); LOCKWORD_COMPARE_AND_SWAP(&mon->entering, 0, UN_USED); } monitorUnlock(mon, self); } } }
void Java_java_lang_Object_notify(void) { OBJECT object = popStackAsType(OBJECT); monitorNotify(object, FALSE); }