/// <summary> /// thread safe method which adds the given node to the top of the list /// </summary> /// <param name="cachenode">node to be added, if the node is added by some other thread it returns</param> internal void AddFirst(LinkedListNode <CacheNode <T, V> > cachenode) { bool added = false; int retrycount = 0; do { bool firstlocktaken = false; bool nextlocktaken = false; bool curlocktaken = false; CacheNode <T, V> nextNode = null; try { retrycount++; firstlocktaken = FirstNode.Value.TryLock(); if (!firstlocktaken) { continue; } curlocktaken = cachenode.Value.TryLock(); if (!curlocktaken) { continue; } if (cachenode.List != null) { return; //added by another thread } if (FirstNode.Next == cachenode) { return; //no need for promotion } nextNode = FirstNode.Next.Value; nextlocktaken = nextNode.TryLock(); if (!nextlocktaken) { continue; } this.list.AddAfter(FirstNode, cachenode); added = true; } finally { if (nextlocktaken) { nextNode.UnlockNode(); } if (curlocktaken) { cachenode.Value.UnlockNode(); } if (firstlocktaken) { FirstNode.Value.UnlockNode(); } if (retrycount % 100 == 0) { Logger.Info($"retryAddFirst {cachenode.Value.key} tries {retrycount}"); } Thread.Sleep(0); } } while (!added); }