summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladimir Sadov <vsadov@microsoft.com>2019-05-31 07:45:03 -0700
committerGitHub <noreply@github.com>2019-05-31 07:45:03 -0700
commit0bbac00d8344195da3c9ee60dad31d0036b7dec0 (patch)
tree94f79735f21e5d7cc4b851861498d2a6e505dad6
parentb8d5b7b760f64d39e00554189ea0e5c66ed6bd62 (diff)
downloadcoreclr-0bbac00d8344195da3c9ee60dad31d0036b7dec0.tar.gz
coreclr-0bbac00d8344195da3c9ee60dad31d0036b7dec0.tar.bz2
coreclr-0bbac00d8344195da3c9ee60dad31d0036b7dec0.zip
Makes GetTotalAllocatedBytes monotonic in nonprecise case. (#24875)
* Makes GetTotalAllocatedBytes monotonic in nonprecise case. Fixes:#24615 * read `dead_threads_non_alloc_bytes` atomically on 32bit platforms * Update src/vm/comutilnative.cpp Co-Authored-By: Jan Kotas <jkotas@microsoft.com>
-rw-r--r--src/vm/comutilnative.cpp28
1 files changed, 23 insertions, 5 deletions
diff --git a/src/vm/comutilnative.cpp b/src/vm/comutilnative.cpp
index 8d3879edf0..3305b8a354 100644
--- a/src/vm/comutilnative.cpp
+++ b/src/vm/comutilnative.cpp
@@ -1293,12 +1293,30 @@ FCIMPL1(INT64, GCInterface::GetTotalAllocatedBytes, CLR_BOOL precise)
if (!precise)
{
- // NOTE: we do not want to make imprecise flavor too slow.
- // As it could be noticed we read 64bit values that may be concurrently updated.
- // Such reads are not guaranteed to be atomic on 32bit and inrare cases we may see torn values resultng in outlier results.
- // That would be extremely rare and in a context of imprecise helper is not worth additional synchronization.
+#ifdef _TARGET_64BIT_
uint64_t unused_bytes = Thread::dead_threads_non_alloc_bytes;
- return GCHeapUtilities::GetGCHeap()->GetTotalAllocatedBytes() - unused_bytes;
+#else
+ // As it could be noticed we read 64bit values that may be concurrently updated.
+ // Such reads are not guaranteed to be atomic on 32bit so extra care should be taken.
+ uint64_t unused_bytes = FastInterlockCompareExchangeLong((LONG64*)& Thread::dead_threads_non_alloc_bytes, 0, 0);
+#endif
+
+ uint64_t allocated_bytes = GCHeapUtilities::GetGCHeap()->GetTotalAllocatedBytes() - unused_bytes;
+
+ // highest reported allocated_bytes. We do not want to report a value less than that even if unused_bytes has increased.
+ static uint64_t high_watermark;
+
+ uint64_t current_high = high_watermark;
+ while (allocated_bytes > current_high)
+ {
+ uint64_t orig = FastInterlockCompareExchangeLong((LONG64*)& high_watermark, allocated_bytes, current_high);
+ if (orig == current_high)
+ return allocated_bytes;
+
+ current_high = orig;
+ }
+
+ return current_high;
}
INT64 allocated;