/** * Updates readers wait count. * * @param lock Lock to update. * @param delta Delta to update. */ private void updateReadersWaitCount(long lock, ReentrantLock lockObj, int delta) { assert lockObj.isHeldByCurrentThread(); while (true) { // Safe to do non-volatile read because of CAS below. long state = GridUnsafe.getLongVolatile(null, lock); long updated = updateState(state, 0, delta, 0); if (GridUnsafe.compareAndSwapLong(null, lock, state, updated)) return; } }
/** * Updates writers wait count. * * @param lock Lock to update. * @param delta Delta to update. */ private void updateWritersWaitCount(long lock, ReentrantLock lockObj, int delta) { assert lockObj.isHeldByCurrentThread(); while (true) { long state = GridUnsafe.getLongVolatile(null, lock); long updated = updateState(state, 0, 0, delta); if (GridUnsafe.compareAndSwapLong(null, lock, state, updated)) return; } } }
/** * @param lock Lock address. */ public boolean tryWriteLock(long lock, int tag) { long state = GridUnsafe.getLongVolatile(null, lock); return checkTag(state, tag) && canWriteLock(state) && GridUnsafe.compareAndSwapLong(null, lock, state, updateState(state, -1, 0, 0)); }
long updated = updateState(state, 0, -1, 0); long updated = updateState(state, 1, -1, 0);
long updated = updateState(state, 0, 0, -1); long updated = updateState(state, -1, 0, -1);
/** * @param lock Lock address. */ public void readUnlock(long lock) { while (true) { long state = GridUnsafe.getLongVolatile(null, lock); if (lockCount(state) <= 0) throw new IllegalMonitorStateException("Attempted to release a read lock while not holding it " + "[lock=" + U.hexLong(lock) + ", state=" + U.hexLong(state) + ']'); long updated = updateState(state, -1, 0, 0); assert updated != 0; if (GridUnsafe.compareAndSwapLong(null, lock, state, updated)) { // Notify monitor if we were CASed to zero and there is a write waiter. if (lockCount(updated) == 0 && writersWaitCount(updated) > 0) { int idx = lockIndex(lock); ReentrantLock lockObj = locks[idx]; lockObj.lock(); try { // Note that we signal all waiters for this stripe. Since not all waiters in this // stripe/index belong to this particular lock, we can't wake up just one of them. writeConditions[idx].signalAll(); } finally { lockObj.unlock(); } } return; } } }
if (GridUnsafe.compareAndSwapLong(null, lock, state, updateState(state, -2, 0, 0))) return true; else if (GridUnsafe.compareAndSwapLong(null, lock, state, updateState(state, -2, 0, 0))) return true; else if (GridUnsafe.compareAndSwapLong(null, lock, state, updateState(state, -1, 0, 1))) break;
/** * @param lock Lock address. */ public boolean writeLock(long lock, int tag) { assert tag != 0; for (int i = 0; i < SPIN_CNT; i++) { long state = GridUnsafe.getLongVolatile(null, lock); assert state != 0; if (!checkTag(state, tag)) return false; if (canWriteLock(state)) { if (GridUnsafe.compareAndSwapLong(null, lock, state, updateState(state, -1, 0, 0))) return true; else // Retry CAS, do not count as spin cycle. i--; } } int idx = lockIndex(lock); ReentrantLock lockObj = locks[idx]; lockObj.lock(); try { updateWritersWaitCount(lock, lockObj, 1); return waitAcquireWriteLock(lock, idx, tag); } finally { lockObj.unlock(); } }
if (GridUnsafe.compareAndSwapLong(null, lock, state, updateState(state, 1, 0, 0))) return true; else
/** * Updates readers wait count. * * @param lock Lock to update. * @param delta Delta to update. */ private void updateReadersWaitCount(long lock, ReentrantLock lockObj, int delta) { assert lockObj.isHeldByCurrentThread(); while (true) { // Safe to do non-volatile read because of CAS below. long state = GridUnsafe.getLongVolatile(null, lock); long updated = updateState(state, 0, delta, 0); if (GridUnsafe.compareAndSwapLong(null, lock, state, updated)) return; } }
/** * Updates writers wait count. * * @param lock Lock to update. * @param delta Delta to update. */ private void updateWritersWaitCount(long lock, ReentrantLock lockObj, int delta) { assert lockObj.isHeldByCurrentThread(); while (true) { long state = GridUnsafe.getLongVolatile(null, lock); long updated = updateState(state, 0, 0, delta); if (GridUnsafe.compareAndSwapLong(null, lock, state, updated)) return; } } }
/** * @param lock Lock address. */ public boolean tryWriteLock(long lock, int tag) { long state = GridUnsafe.getLongVolatile(null, lock); return checkTag(state, tag) && canWriteLock(state) && GridUnsafe.compareAndSwapLong(null, lock, state, updateState(state, -1, 0, 0)); }
long updated = updateState(state, 0, -1, 0); long updated = updateState(state, 1, -1, 0);
long updated = updateState(state, 0, 0, -1); long updated = updateState(state, -1, 0, -1);
/** * @param lock Lock address. */ public void readUnlock(long lock) { while (true) { long state = GridUnsafe.getLongVolatile(null, lock); if (lockCount(state) <= 0) throw new IllegalMonitorStateException("Attempted to release a read lock while not holding it " + "[lock=" + U.hexLong(lock) + ", state=" + U.hexLong(state) + ']'); long updated = updateState(state, -1, 0, 0); assert updated != 0; if (GridUnsafe.compareAndSwapLong(null, lock, state, updated)) { // Notify monitor if we were CASed to zero and there is a write waiter. if (lockCount(updated) == 0 && writersWaitCount(updated) > 0) { int idx = lockIndex(lock); ReentrantLock lockObj = locks[idx]; lockObj.lock(); try { // Note that we signal all waiters for this stripe. Since not all waiters in this // stripe/index belong to this particular lock, we can't wake up just one of them. writeConditions[idx].signalAll(); } finally { lockObj.unlock(); } } return; } } }
if (GridUnsafe.compareAndSwapLong(null, lock, state, updateState(state, -2, 0, 0))) return true; else if (GridUnsafe.compareAndSwapLong(null, lock, state, updateState(state, -2, 0, 0))) return true; else if (GridUnsafe.compareAndSwapLong(null, lock, state, updateState(state, -1, 0, 1))) break;
/** * @param lock Lock address. */ public boolean writeLock(long lock, int tag) { assert tag != 0; for (int i = 0; i < SPIN_CNT; i++) { long state = GridUnsafe.getLongVolatile(null, lock); assert state != 0; if (!checkTag(state, tag)) return false; if (canWriteLock(state)) { if (GridUnsafe.compareAndSwapLong(null, lock, state, updateState(state, -1, 0, 0))) return true; else // Retry CAS, do not count as spin cycle. i--; } } int idx = lockIndex(lock); ReentrantLock lockObj = locks[idx]; lockObj.lock(); try { updateWritersWaitCount(lock, lockObj, 1); return waitAcquireWriteLock(lock, idx, tag); } finally { lockObj.unlock(); } }
if (GridUnsafe.compareAndSwapLong(null, lock, state, updateState(state, 1, 0, 0))) return true; else