Esempio n. 1
0
            private static ThreadLocalLockEntry GetOrCreateCurrentSlow(long lockID, ThreadLocalLockEntry headEntry)
            {
                Debug.Assert(lockID != 0);
                Debug.Assert(headEntry == t_lockEntryHead);
                Debug.Assert(headEntry == null || headEntry._lockID != lockID);

                ThreadLocalLockEntry entry = null;
                ThreadLocalLockEntry emptyEntryPrevious = null;
                ThreadLocalLockEntry emptyEntry = null;

                if (headEntry != null)
                {
                    if (headEntry.IsFree)
                    {
                        emptyEntry = headEntry;
                    }

                    for (ThreadLocalLockEntry previousEntry = headEntry, currentEntry = headEntry._next;
                        currentEntry != null;
                        previousEntry = currentEntry, currentEntry = currentEntry._next)
                    {
                        if (currentEntry._lockID == lockID)
                        {
                            VerifyNoNonemptyEntryInListAfter(lockID, currentEntry);

                            // Unlink the entry, preparing to move it to the head of the list
                            previousEntry._next = currentEntry._next;
                            entry = currentEntry;
                            break;
                        }

                        if (emptyEntry == null && currentEntry.IsFree)
                        {
                            // Record the first empty entry in case there is no existing entry
                            emptyEntryPrevious = previousEntry;
                            emptyEntry = currentEntry;
                        }
                    }
                }

                if (entry == null)
                {
                    if (emptyEntry != null)
                    {
                        // Claim the first empty entry that was found
                        emptyEntry._lockID = lockID;

                        // Unlink the empty entry, preparing to move it to the head of the list
                        if (emptyEntryPrevious == null)
                        {
                            Debug.Assert(emptyEntry == headEntry);
                            return emptyEntry;
                        }
                        emptyEntryPrevious._next = emptyEntry._next;
                        entry = emptyEntry;
                    }
                    else
                    {
                        entry = new ThreadLocalLockEntry(lockID);
                    }
                }

                // Insert the entry at the head of the list
                Debug.Assert(entry._lockID == lockID);
                entry._next = headEntry;
                t_lockEntryHead = entry;
                return entry;
            }
Esempio n. 2
0
            private static void VerifyNoNonemptyEntryInListAfter(long lockID, ThreadLocalLockEntry afterEntry)
            {
                Debug.Assert(lockID != 0);
                Debug.Assert(afterEntry != null);

                for (ThreadLocalLockEntry currentEntry = afterEntry._next;
                    currentEntry != null;
                    currentEntry = currentEntry._next)
                {
                    Debug.Assert(currentEntry._lockID != lockID || currentEntry.IsFree);
                }
            }