コード例 #1
0
ファイル: OffHeapPageLock.cs プロジェクト: Neo4Net/Neo4Net
        /// <summary>
        /// Try taking a concurrent write lock. Multiple write locks can be held at the same time. Write locks will
        /// invalidate any optimistic read lock that overlaps with them, and write locks will make any attempt at grabbing
        /// an exclusive lock fail. If an exclusive lock is currently held, then the attempt to take a write lock will fail.
        /// <para>
        /// Write locks must be paired with a corresponding <seealso cref="unlockWrite(long)"/>.
        ///
        /// </para>
        /// </summary>
        /// <returns> {@code true} if the write lock was taken, {@code false} otherwise. </returns>
        public static bool TryWriteLock(long address)
        {
            long s;
            long n;

            for ( ; ;)
            {
                s = GetState(address);
                bool unwritablyLocked   = (s & _exlMask) != 0;
                bool writeCountOverflow = (s & _cntMask) == _cntMask;

                // bitwise-OR to reduce branching and allow more ILP
                if (unwritablyLocked | writeCountOverflow)
                {
                    return(FailWriteLock(s, writeCountOverflow));
                }

                n = s + _cntUnit | _modMask;
                if (CompareAndSetState(address, s, n))
                {
                    UnsafeUtil.storeFence();
                    return(true);
                }
            }
        }
コード例 #2
0
ファイル: OffHeapPageLock.cs プロジェクト: Neo4Net/Neo4Net
        /// <summary>
        /// Grab the exclusive lock if it is immediately available. Exclusive locks will invalidate any overlapping
        /// optimistic read lock, and fail write and flush locks. If any write or flush locks are currently taken, or if
        /// the exclusive lock is already taken, then the attempt to grab an exclusive lock will fail.
        /// <para>
        /// Successfully grabbed exclusive locks must always be paired with a corresponding <seealso cref="unlockExclusive(long)"/>.
        ///
        /// </para>
        /// </summary>
        /// <returns> {@code true} if we successfully got the exclusive lock, {@code false} otherwise. </returns>
        public static bool TryExclusiveLock(long address)
        {
            long s   = GetState(address);
            bool res = ((s & _unlMask) == 0) && CompareAndSetState(address, s, s + _exlMask);

            UnsafeUtil.storeFence();
            return(res);
        }
コード例 #3
0
ファイル: OffHeapPageLock.cs プロジェクト: Neo4Net/Neo4Net
        /// <summary>
        /// Grab the flush lock if it is immediately available. Flush locks prevent overlapping exclusive locks,
        /// but do not invalidate optimistic read locks, nor do they prevent overlapping write locks. Only one flush lock
        /// can be held at a time. If any flush or exclusive lock is already held, the attempt to take the flush lock will
        /// fail.
        /// <para>
        /// Successfully grabbed flush locks must always be paired with a corresponding
        /// <seealso cref="unlockFlush(long, long, bool)"/>.
        ///
        /// </para>
        /// </summary>
        /// <returns> If the lock is successfully grabbed, the method will return a stamp value that must be passed to the
        /// <seealso cref="unlockFlush(long, long, bool)"/>, and which is used for detecting any overlapping write locks. If the
        /// flush lock could not be taken, {@code 0} will be returned. </returns>
        public static long TryFlushLock(long address)
        {
            long s = GetState(address);

            if ((s & _faeMask) == 0)
            {
                long n   = s + _flsMask;
                bool res = CompareAndSetState(address, s, n);
                UnsafeUtil.storeFence();
                return(res ? n : 0);
            }
            return(0);
        }
コード例 #4
0
ファイル: OffHeapPageLock.cs プロジェクト: Neo4Net/Neo4Net
        public static long UnlockWriteAndTryTakeFlushLock(long address)
        {
            long s;
            long n;
            long r;

            do
            {
                r = 0;
                s = GetState(address);
                if ((s & _cntMask) == 0)
                {
                    ThrowUnmatchedUnlockWrite(s);
                }
                n = NextSeq(s) - _cntUnit;
                if ((n & _faeMask) == 0)
                {
                    n += _flsMask;
                    r  = n;
                }
            } while (!CompareAndSetState(address, s, n));
            UnsafeUtil.storeFence();
            return(r);
        }