| 207 | } |
| 208 | |
| 209 | void* ExperimentalPMemAllocator::AllocateRaw(size_t alignment, size_t size) { |
| 210 | void* ret = nullptr; |
| 211 | int t_id = MaybeInitAccessThread(); |
| 212 | if (t_id < 0) { |
| 213 | LOG(FATAL) << "Experimental PMem Allocator: Too many thread access " |
| 214 | "allocator! max threads: " |
| 215 | << kMaxAccessThreads; |
| 216 | return nullptr; |
| 217 | } |
| 218 | uint32_t b_size = Size2BlockSize(size); |
| 219 | uint32_t aligned_size = b_size * block_size_; |
| 220 | if (aligned_size > max_allocation_size_ || aligned_size == 0) { |
| 221 | LOG(FATAL) << "Experimental PMem Allocator: Allocating size: " << size |
| 222 | << ", is 0 or larger than PMem allocator max allocation size " |
| 223 | << max_allocation_size_; |
| 224 | return nullptr; |
| 225 | } |
| 226 | auto& thread_cache = thread_cache_[t_id]; |
| 227 | for (auto i = b_size; i < thread_cache.freelists.size(); i++) { |
| 228 | if (thread_cache.segments[i].size < aligned_size) { |
| 229 | // Fetch free list from pool |
| 230 | { |
| 231 | std::lock_guard<spin_lock> lg(thread_cache.locks[i]); |
| 232 | if (thread_cache.freelists[i].empty()) { |
| 233 | pool_.FetchEntryList(thread_cache.freelists[i], i); |
| 234 | } |
| 235 | // Get space from free list |
| 236 | if (thread_cache.freelists[i].size() > 0) { |
| 237 | ret = thread_cache.freelists[i].back(); |
| 238 | thread_cache.freelists[i].pop_back(); |
| 239 | break; |
| 240 | } |
| 241 | } |
| 242 | // Allocate a new segment for requesting block size |
| 243 | if (!AllocateSegmentSpace(&thread_cache.segments[b_size], b_size)) { |
| 244 | continue; |
| 245 | } else { |
| 246 | i = b_size; |
| 247 | } |
| 248 | } |
| 249 | assert(thread_cache.segments[i].size >= aligned_size); |
| 250 | ret = thread_cache.segments[i].addr; |
| 251 | thread_cache.segments[i].size -= aligned_size; |
| 252 | thread_cache.segments[i].addr = |
| 253 | (char*)thread_cache.segments[i].addr + aligned_size; |
| 254 | break; |
| 255 | } |
| 256 | |
| 257 | if (pmem_allocator_collect_stats) { |
| 258 | const std::size_t alloc_size = AllocatedSize(ret); |
| 259 | mutex_lock l(mu_); |
| 260 | ++stats_.num_allocs; |
| 261 | stats_.bytes_in_use += alloc_size; |
| 262 | stats_.peak_bytes_in_use = |
| 263 | std::max<int64>(stats_.peak_bytes_in_use, stats_.bytes_in_use); |
| 264 | stats_.largest_alloc_size = |
| 265 | std::max<int64>(stats_.largest_alloc_size, alloc_size); |
| 266 |
nothing calls this directly
no test coverage detected