Beispiel #1
0
 @Uninterruptible
 @NoNullCheck
 public static boolean holdsLock(Object o, Offset lockOffset, RVMThread thread) {
   for (int cnt = 0; ; ++cnt) {
     int tid = thread.getLockingId();
     Word bits = Magic.getWordAtOffset(o, lockOffset);
     if (bits.and(TL_STAT_MASK).EQ(TL_STAT_BIASABLE)) {
       // if locked, then it is locked with a thin lock
       return bits.and(TL_THREAD_ID_MASK).toInt() == tid && !bits.and(TL_LOCK_COUNT_MASK).isZero();
     } else if (bits.and(TL_STAT_MASK).EQ(TL_STAT_THIN)) {
       return bits.and(TL_THREAD_ID_MASK).toInt() == tid;
     } else {
       if (VM.VerifyAssertions) VM._assert(bits.and(TL_STAT_MASK).EQ(TL_STAT_FAT));
       // if locked, then it is locked with a fat lock
       Lock l = Lock.getLock(getLockIndex(bits));
       if (l != null) {
         l.mutex.lock();
         boolean result = (l.getOwnerId() == tid && l.getLockedObject() == o);
         l.mutex.unlock();
         return result;
       }
     }
     RVMThread.yield();
   }
 }
Beispiel #2
0
 /**
  * Promotes a light-weight lock to a heavy-weight lock. If this returns the lock that you gave it,
  * its mutex will be locked; otherwise, its mutex will be unlocked. Hence, calls to this method
  * should always be followed by a condition lock() or unlock() call.
  *
  * @param o the object to get a heavy-weight lock
  * @param lockOffset the offset of the thin lock word in the object.
  * @return the inflated lock; either the one you gave, or another one, if the lock was inflated by
  *     some other thread.
  */
 @NoNullCheck
 @Unpreemptible
 protected static Lock attemptToInflate(Object o, Offset lockOffset, Lock l) {
   if (false) VM.sysWriteln("l = ", Magic.objectAsAddress(l));
   l.mutex.lock();
   for (int cnt = 0; ; ++cnt) {
     Word bits = Magic.getWordAtOffset(o, lockOffset);
     // check to see if another thread has already created a fat lock
     if (isFat(bits)) {
       if (trace) {
         VM.sysWriteln(
             "Thread #",
             RVMThread.getCurrentThreadSlot(),
             ": freeing lock ",
             Magic.objectAsAddress(l),
             " because we had a double-inflate");
       }
       Lock result = Lock.getLock(getLockIndex(bits));
       if (result == null || result.lockedObject != o) {
         continue; /* this is nasty.  this will happen when a lock
                   is deflated. */
       }
       Lock.free(l);
       l.mutex.unlock();
       return result;
     }
     if (VM.VerifyAssertions) VM._assert(l != null);
     if (attemptToMarkInflated(o, lockOffset, bits, l.index, cnt)) {
       l.setLockedObject(o);
       l.setOwnerId(getLockOwner(bits));
       if (l.getOwnerId() != 0) {
         l.setRecursionCount(getRecCount(bits));
       } else {
         if (VM.VerifyAssertions) VM._assert(l.getRecursionCount() == 0);
       }
       return l;
     }
     // contention detected, try again
   }
 }