Пример #1
0
        private static bool IsRWEntryEmpty(ReaderWriterCount rwc)
        {
            if (rwc.ThreadId == -1)
            {
                return(true);
            }

            if (rwc.ReaderCount == 0 && rwc.Rc == null)
            {
                return(true);
            }

            if (rwc.ReaderCount == 0 && rwc.Rc.WriterCount == 0 && rwc.Rc.UpgradeCount == 0)
            {
                return(true);
            }

            return(false);
        }
Пример #2
0
        /// <summary>
        /// This routine retrieves/sets the per-thread counts needed to enforce the
        /// various rules related to acquiring the lock. It's a simple hash table,
        /// where the first entry is pre-allocated for optimizing the common case.
        /// After the first element has been allocated, duplicates are kept of in
        /// linked-list. The entries are never freed, and the max size of the
        /// table would be bounded by the max number of threads that held the lock
        /// simultaneously.
        ///
        /// DontAllocate is set to true if the caller just wants to get an existing
        /// entry for this thread, but doesn't want to add one if an existing one
        /// could not be found.
        /// </summary>
        private ReaderWriterCount GetThreadRWCount(int id, bool dontAllocate)
        {
            int hash = id & HashTableSize;
            ReaderWriterCount firstfound = null;

#if DEBUG
            Debug.Assert(MyLockHeld);
#endif

            if (null == _rwc[hash])
            {
                if (dontAllocate)
                {
                    return(null);
                }

                _rwc[hash] = new ReaderWriterCount(_isReentrant);
            }

            if (_rwc[hash].ThreadId == id)
            {
                return(_rwc[hash]);
            }

            if (IsRWEntryEmpty(_rwc[hash]) && !dontAllocate)
            {
                //No more entries in chain, so no more searching required.
                if (_rwc[hash].Next == null)
                {
                    _rwc[hash].ThreadId = id;
                    return(_rwc[hash]);
                }

                firstfound = _rwc[hash];
            }

            //SlowPath

            var temp = _rwc[hash].Next;

            while (temp != null)
            {
                if (temp.ThreadId == id)
                {
                    return(temp);
                }

                if (firstfound == null)
                {
                    if (IsRWEntryEmpty(temp))
                    {
                        firstfound = temp;
                    }
                }

                temp = temp.Next;
            }

            if (dontAllocate)
            {
                return(null);
            }

            if (firstfound == null)
            {
                temp = new ReaderWriterCount(_isReentrant)
                {
                    ThreadId = id,
                    Next     = _rwc[hash].Next
                };
                _rwc[hash].Next = temp;
                return(temp);
            }

            firstfound.ThreadId = id;
            return(firstfound);
        }
Пример #3
0
 private static bool IsRwHashEntryChanged(ReaderWriterCount lrwc, int id)
 {
     return(lrwc.ThreadId != id);
 }