| 221 | } |
| 222 | |
| 223 | void* BFCAllocator::AllocateRaw(size_t unused_alignment, size_t num_bytes, |
| 224 | const AllocationAttributes& allocation_attr) { |
| 225 | VLOG(3) << "AllocateRaw " << Name() << " " << num_bytes; |
| 226 | void* result = nullptr; |
| 227 | if (allocation_attr.no_retry_on_failure) { |
| 228 | // Return immediately upon the first failure if this is for allocating an |
| 229 | // optional scratch space. |
| 230 | bool dump_log_on_failure = VLOG_IS_ON(2); |
| 231 | uint64 freed_by_count = 0; |
| 232 | if (allocation_attr.freed_by_func != nullptr) { |
| 233 | freed_by_count = (*allocation_attr.freed_by_func)(); |
| 234 | } |
| 235 | result = AllocateRawInternal(unused_alignment, num_bytes, |
| 236 | dump_log_on_failure, freed_by_count); |
| 237 | if (result == nullptr) { |
| 238 | static std::atomic<int32> log_counter{0}; |
| 239 | int32 counter_value = log_counter.load(std::memory_order_relaxed); |
| 240 | if (counter_value < 10) { |
| 241 | log_counter.store(counter_value + 1, std::memory_order_relaxed); |
| 242 | LOG(WARNING) |
| 243 | << "Allocator (" << Name() << ") ran out of memory trying " |
| 244 | << "to allocate " << strings::HumanReadableNumBytes(num_bytes) |
| 245 | << " with freed_by_count=" << freed_by_count |
| 246 | |
| 247 | << ". The caller indicates that this is not a failure, but" |
| 248 | << " may mean that there could be performance gains if more" |
| 249 | << " memory were available."; |
| 250 | } |
| 251 | } |
| 252 | return result; |
| 253 | } else { |
| 254 | result = AllocateRawInternalWithRetry(unused_alignment, num_bytes, |
| 255 | allocation_attr); |
| 256 | } |
| 257 | VLOG(3) << "AllocateRaw " << Name() << " " << num_bytes << " " |
| 258 | << result; |
| 259 | return result; |
| 260 | } |
| 261 | |
| 262 | // static |
| 263 | size_t BFCAllocator::RoundedBytes(size_t bytes) { |