You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// There is no overload which only takes capacity as the parameter
117
-
// Using the DefaultConcurrencyLevel defined in the ConcurrentDictionary class: https://github.com/dotnet/runtime/blob/v7.0.5/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentDictionary.cs#L2020
137
+
// Using the DefaultConcurrencyLevel defined in the ConcurrentDictionary class: https://github.com/dotnet/runtime/blob/v10.0.0/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentDictionary.cs#L2054
118
138
// We expect at the most (user provided cardinality limit) * 2 entries- one for sorted and one for unsorted input
// Add all the indices except for the reserved ones to the queue so that threads have
123
152
// readily available access to these MetricPoints for their use.
@@ -685,57 +714,69 @@ private int LookupAggregatorStoreForDeltaWithReclaim(KeyValuePair<string, object
685
714
686
715
// If the running thread created a new MetricPoint, then the Snapshot method cannot reclaim that MetricPoint because MetricPoint is initialized with a ReferenceCount of 1.
687
716
// It can simply return the index.
688
-
689
717
if(!newMetricPointCreated)
690
718
{
691
-
// If the running thread did not create the MetricPoint, it could be working on an index that has been reclaimed by Snapshot method.
692
-
// This could happen if the thread get switched out by CPU after it retrieves the index but the Snapshot method reclaims it before the thread wakes up again.
// Rare case: Snapshot method had already marked the MetricPoint available for reuse as it has not been updated in last collect cycle.
700
-
701
-
// Example scenario:
702
-
// Thread T1 wants to record a measurement for (k1,v1).
703
-
// Thread T1 creates a new MetricPoint at index 100 and adds an entry for (k1,v1) in the dictionary with the relevant LookupData value; ReferenceCount of the MetricPoint is 1 at this point.
704
-
// Thread T1 completes the update and decrements the ReferenceCount to 0.
705
-
// Later, another update thread (could be T1 as well) wants to record a measurement for (k1,v1)
706
-
// It looks up the dictionary and retrieves the index as 100. ReferenceCount for the MetricPoint is 0 at this point.
707
-
// This update thread gets switched out by the CPU.
708
-
// With the reclaim behavior, Snapshot method reclaims the index 100 as the MetricPoint for the index has NoCollectPending and has a ReferenceCount of 0.
709
-
// Snapshot thread sets the ReferenceCount to int.MinValue.
710
-
// The update thread wakes up and increments the ReferenceCount but finds the value to be negative.
// Rare case: Another thread with different input tags could have reclaimed this MetricPoint if it was freed up by Snapshot method.
718
-
719
-
// Example scenario:
720
-
// Thread T1 wants to record a measurement for (k1,v1).
721
-
// Thread T1 creates a new MetricPoint at index 100 and adds an entry for (k1,v1) in the dictionary with the relevant LookupData value; ReferenceCount of the MetricPoint is 1 at this point.
722
-
// Thread T1 completes the update and decrements the ReferenceCount to 0.
723
-
// Later, another update thread T2 (could be T1 as well) wants to record a measurement for (k1,v1)
724
-
// It looks up the dictionary and retrieves the index as 100. ReferenceCount for the MetricPoint is 0 at this point.
725
-
// This update thread T2 gets switched out by the CPU.
726
-
// With the reclaim behavior, Snapshot method reclaims the index 100 as the MetricPoint for the index has NoCollectPending and has a ReferenceCount of 0.
727
-
// Snapshot thread sets the ReferenceCount to int.MinValue.
728
-
// An update thread T3 wants to record a measurement for (k2,v2).
729
-
// Thread T3 looks for an available index from the queue and finds index 100.
730
-
// Thread T3 creates a new MetricPoint at index 100 and adds an entry for (k2,v2) in the dictionary with the LookupData value for (k2,v2). ReferenceCount of the MetricPoint is 1 at this point.
731
-
// The update thread T2 wakes up and increments the ReferenceCount and finds the value to be positive but the LookupData value does not match the one for (k1,v1).
732
-
733
-
// Remove reference since its not the right MetricPoint.
// If the running thread did not create the MetricPoint, it could be working on an index that has been reclaimed by Snapshot method.
734
+
// This could happen if the thread get switched out by CPU after it retrieves the index but the Snapshot method reclaims it before the thread wakes up again.
// Rare case: Snapshot method had already marked the MetricPoint available for reuse as it has not been updated in last collect cycle.
742
+
743
+
// Example scenario:
744
+
// Thread T1 wants to record a measurement for (k1,v1).
745
+
// Thread T1 creates a new MetricPoint at index 100 and adds an entry for (k1,v1) in the dictionary with the relevant LookupData value; ReferenceCount of the MetricPoint is 1 at this point.
746
+
// Thread T1 completes the update and decrements the ReferenceCount to 0.
747
+
// Later, another update thread (could be T1 as well) wants to record a measurement for (k1,v1)
748
+
// It looks up the dictionary and retrieves the index as 100. ReferenceCount for the MetricPoint is 0 at this point.
749
+
// This update thread gets switched out by the CPU.
750
+
// With the reclaim behavior, Snapshot method reclaims the index 100 as the MetricPoint for the index has NoCollectPending and has a ReferenceCount of 0.
751
+
// Snapshot thread sets the ReferenceCount to int.MinValue.
752
+
// The update thread wakes up and increments the ReferenceCount but finds the value to be negative.
// Rare case: Another thread with different input tags could have reclaimed this MetricPoint if it was freed up by Snapshot method.
760
+
761
+
// Example scenario:
762
+
// Thread T1 wants to record a measurement for (k1,v1).
763
+
// Thread T1 creates a new MetricPoint at index 100 and adds an entry for (k1,v1) in the dictionary with the relevant LookupData value; ReferenceCount of the MetricPoint is 1 at this point.
764
+
// Thread T1 completes the update and decrements the ReferenceCount to 0.
765
+
// Later, another update thread T2 (could be T1 as well) wants to record a measurement for (k1,v1)
766
+
// It looks up the dictionary and retrieves the index as 100. ReferenceCount for the MetricPoint is 0 at this point.
767
+
// This update thread T2 gets switched out by the CPU.
768
+
// With the reclaim behavior, Snapshot method reclaims the index 100 as the MetricPoint for the index has NoCollectPending and has a ReferenceCount of 0.
769
+
// Snapshot thread sets the ReferenceCount to int.MinValue.
770
+
// An update thread T3 wants to record a measurement for (k2,v2).
771
+
// Thread T3 looks for an available index from the queue and finds index 100.
772
+
// Thread T3 creates a new MetricPoint at index 100 and adds an entry for (k2,v2) in the dictionary with the LookupData value for (k2,v2). ReferenceCount of the MetricPoint is 1 at this point.
773
+
// The update thread T2 wakes up and increments the ReferenceCount and finds the value to be positive but the LookupData value does not match the one for (k1,v1).
774
+
775
+
// Remove reference since its not the right MetricPoint.
0 commit comments