| 189 | } // anonymous namespace |
| 190 | |
| 191 | int64_t CurrentConsumption() { |
| 192 | #ifdef TCMALLOC_ENABLED |
| 193 | const int64_t kReadIntervalMicros = 50000; |
| 194 | static Atomic64 last_read_time = 0; |
| 195 | static simple_spinlock read_lock; |
| 196 | static Atomic64 consumption = 0; |
| 197 | uint64_t time = GetMonoTimeMicros(); |
| 198 | if (time > last_read_time + kReadIntervalMicros && read_lock.try_lock()) { |
| 199 | base::subtle::NoBarrier_Store(&consumption, GetTCMallocCurrentAllocatedBytes()); |
| 200 | // Re-fetch the time after getting the consumption. This way, in case fetching |
| 201 | // consumption is extremely slow for some reason (eg due to lots of contention |
| 202 | // in tcmalloc) we at least ensure that we wait at least another full interval |
| 203 | // before fetching the information again. |
| 204 | time = GetMonoTimeMicros(); |
| 205 | base::subtle::NoBarrier_Store(&last_read_time, time); |
| 206 | read_lock.unlock(); |
| 207 | } |
| 208 | |
| 209 | return base::subtle::NoBarrier_Load(&consumption); |
| 210 | #else |
| 211 | // Without tcmalloc, we have no reliable way of determining our own heap |
| 212 | // size (e.g. mallinfo doesn't work in ASAN builds). So, we'll fall back |
| 213 | // to just looking at the sum of our tracked memory. |
| 214 | return MemTracker::GetRootTracker()->consumption(); |
| 215 | #endif |
| 216 | } |
| 217 | |
| 218 | int64_t HardLimit() { |
| 219 | InitLimits(); |