diff options
author | Vladimir Sadov <vsadov@microsoft.com> | 2019-05-31 07:45:03 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-05-31 07:45:03 -0700 |
commit | 0bbac00d8344195da3c9ee60dad31d0036b7dec0 (patch) | |
tree | 94f79735f21e5d7cc4b851861498d2a6e505dad6 | |
parent | b8d5b7b760f64d39e00554189ea0e5c66ed6bd62 (diff) | |
download | coreclr-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.cpp | 28 |
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; |