internal static OverlappedData GetOverlappedData(Overlapped overlapped) { OverlappedData data = null; Interlocked.Exchange(ref m_overlappedDataCacheAccessed, 1); while (true) { OverlappedDataCacheLine overlappedDataCache = s_firstFreeCacheLine; if (overlappedDataCache == null) { overlappedDataCache = m_overlappedDataCache; } while (overlappedDataCache != null) { for (short i = 0; i < 0x10; i = (short)(i + 1)) { if (overlappedDataCache.m_items[i] != null) { data = Interlocked.Exchange <OverlappedData>(ref overlappedDataCache.m_items[i], null); if (data != null) { s_firstFreeCacheLine = overlappedDataCache; data.m_overlapped = overlapped; return(data); } } } overlappedDataCache = overlappedDataCache.m_next; } GrowOverlappedDataCache(); } }
//static private int m_CollectionCount; /* * static private int m_Create = 0; * static private int m_Total = 0; * static private int m_Cache = 0; */ // Setup the cache. private static void GrowOverlappedDataCache() { OverlappedDataCacheLine data = new OverlappedDataCacheLine(); if (m_overlappedDataCache == null) { // Add the first node in the list if (Interlocked.CompareExchange <OverlappedDataCacheLine>(ref m_overlappedDataCache, data, null) == null) { // Use GC to remove items. new OverlappedDataCache(); return; } } // If there is already a first node in the list we'll add the new OverlappedDataCacheLine at the end if (m_cleanupObjectCount == 0) { new OverlappedDataCache(); } while (true) { // Chain the new node OverlappedDataCacheLine walk = m_overlappedDataCache; while (null != walk && null != walk.m_next) { // There's a race with the finalizer here between testing if walk.m_next is null and assigning // Note 1. // If walk has been removed from the list by the finalizer thread we still have a valid // walk.next chain that will eventually lead us back to the original list, or to NULL. // If NULL see Note 4 below. // Note 2. // If walk.next was removed from list the next time through the loop we'll be in the // situation described in Note 1. // Note 3. // If walk.next was set to NULL by the finalizer thread we'll need to test for that in the // while condition and after exiting the loop. walk = walk.m_next; } // if walk has become null (due to finalizer race) after the while test // simply return and let GetOverlappedData retry! if (null == walk) { return; } // Add the new OverlappedDataCacheLine at the end of the list. // Note 4. // Even if the node that walk points to has been removed from the list we simply // add the new node to an unreachable graph. GetOverlappedData() will notice that // there are still no empty OverlappedData elements and call us again. The // "unreachable list" will be reclaimed during the next GC. if (Interlocked.CompareExchange <OverlappedDataCacheLine>(ref walk.m_next, data, null) == null) { break; } } }
private static void GrowOverlappedDataCache() { OverlappedDataCacheLine line = new OverlappedDataCacheLine(); if ((m_overlappedDataCache == null) && (Interlocked.CompareExchange <OverlappedDataCacheLine>(ref m_overlappedDataCache, line, null) == null)) { new OverlappedDataCache(); } else { OverlappedDataCacheLine line2; if (m_cleanupObjectCount == 0) { new OverlappedDataCache(); } do { for (line2 = m_overlappedDataCache; (line2 != null) && (line2.m_next != null); line2 = line2.m_next) { } }while ((line2 != null) && (Interlocked.CompareExchange <OverlappedDataCacheLine>(ref line2.m_next, line, null) != null)); } }
internal static OverlappedData GetOverlappedData(Overlapped overlapped) { OverlappedData overlappedData = null; Interlocked.Exchange(ref m_overlappedDataCacheAccessed, 1); while (true) { OverlappedDataCacheLine walk = m_overlappedDataCache; while (null != walk) { for (short i = 0; i < OverlappedDataCacheLine.CacheSize; i++) { if (walk.m_items[i] != null) { overlappedData = Interlocked.Exchange <OverlappedData>(ref walk.m_items[i], null); if (overlappedData != null) { overlappedData.m_overlapped = overlapped; return(overlappedData); } } } walk = walk.m_next; } GrowOverlappedDataCache(); } /* * Interlocked.Increment(ref m_Total); * Console.WriteLine("OverlappedDataCache get " + m_Total + * " create " + m_Create + * " Cache " + m_Cache); */ }
internal static void CacheOverlappedData(OverlappedData data) { data.ReInitialize(); data.m_cacheLine.m_items[data.m_slot] = data; s_firstFreeCacheLine = null; }
private static void GrowOverlappedDataCache() { OverlappedDataCacheLine line = new OverlappedDataCacheLine(); if ((m_overlappedDataCache == null) && (Interlocked.CompareExchange<OverlappedDataCacheLine>(ref m_overlappedDataCache, line, null) == null)) { new OverlappedDataCache(); } else { OverlappedDataCacheLine line2; if (m_cleanupObjectCount == 0) { new OverlappedDataCache(); } do { for (line2 = m_overlappedDataCache; (line2 != null) && (line2.m_next != null); line2 = line2.m_next) { } } while ((line2 != null) && (Interlocked.CompareExchange<OverlappedDataCacheLine>(ref line2.m_next, line, null) != null)); } }
internal static OverlappedData GetOverlappedData(Overlapped overlapped) { OverlappedData data = null; Interlocked.Exchange(ref m_overlappedDataCacheAccessed, 1); while (true) { OverlappedDataCacheLine overlappedDataCache = s_firstFreeCacheLine; if (overlappedDataCache == null) { overlappedDataCache = m_overlappedDataCache; } while (overlappedDataCache != null) { for (short i = 0; i < 0x10; i = (short) (i + 1)) { if (overlappedDataCache.m_items[i] != null) { data = Interlocked.Exchange<OverlappedData>(ref overlappedDataCache.m_items[i], null); if (data != null) { s_firstFreeCacheLine = overlappedDataCache; data.m_overlapped = overlapped; return data; } } } overlappedDataCache = overlappedDataCache.m_next; } GrowOverlappedDataCache(); } }
internal OverlappedData(OverlappedDataCacheLine cacheLine) { this.m_cacheLine = cacheLine; }
//static private int m_CollectionCount; /* static private int m_Create = 0; static private int m_Total = 0; static private int m_Cache = 0; */ // Setup the cache. private static void GrowOverlappedDataCache() { OverlappedDataCacheLine data = new OverlappedDataCacheLine(); if (m_overlappedDataCache == null) { // Add the first node in the list if (Interlocked.CompareExchange<OverlappedDataCacheLine>(ref m_overlappedDataCache, data, null) == null) { // Use GC to remove items. new OverlappedDataCache(); return; } } // If there is already a first node in the list we'll add the new OverlappedDataCacheLine at the end if (m_cleanupObjectCount == 0) { new OverlappedDataCache(); } while (true) { // Chain the new node OverlappedDataCacheLine walk = m_overlappedDataCache; while (null != walk && null != walk.m_next) { // There's a race with the finalizer here between testing if walk.m_next is null and assigning // Note 1. // If walk has been removed from the list by the finalizer thread we still have a valid // walk.next chain that will eventually lead us back to the original list, or to NULL. // If NULL see Note 4 below. // Note 2. // If walk.next was removed from list the next time through the loop we'll be in the // situation described in Note 1. // Note 3. // If walk.next was set to NULL by the finalizer thread we'll need to test for that in the // while condition and after exiting the loop. walk = walk.m_next; } // if walk has become null (due to finalizer race) after the while test // simply return and let GetOverlappedData retry! if (null == walk) return; // Add the new OverlappedDataCacheLine at the end of the list. // Note 4. // Even if the node that walk points to has been removed from the list we simply // add the new node to an unreachable graph. GetOverlappedData() will notice that // there are still no empty OverlappedData elements and call us again. The // "unreachable list" will be reclaimed during the next GC. if (Interlocked.CompareExchange<OverlappedDataCacheLine>(ref walk.m_next, data, null) == null) break; } }
internal OverlappedData(OverlappedDataCacheLine cacheLine) { m_cacheLine = cacheLine; }
internal static OverlappedData GetOverlappedData(Overlapped overlapped) { OverlappedData overlappedData = null; Interlocked.Exchange(ref m_overlappedDataCacheAccessed, 1); while (true) { OverlappedDataCacheLine walk = s_firstFreeCacheLine; if(walk == null) walk = m_overlappedDataCache; while (null != walk) { for (short i = 0; i < OverlappedDataCacheLine.CacheSize; i ++) { if (walk.m_items[i] != null) { overlappedData = Interlocked.Exchange<OverlappedData>(ref walk.m_items[i], null); if (overlappedData != null) { s_firstFreeCacheLine = walk; overlappedData.m_overlapped = overlapped; return overlappedData; } } } walk = walk.m_next; } GrowOverlappedDataCache(); } /* Interlocked.Increment(ref m_Total); Console.WriteLine("OverlappedDataCache get " + m_Total + " create " + m_Create + " Cache " + m_Cache); */ }