/////////////// AccessSpreader
template struct AccessSpreader<std::atomic>;
+SimpleAllocator::SimpleAllocator(size_t allocSize, size_t sz)
+ : allocSize_{allocSize}, sz_(sz) {}
+
+SimpleAllocator::~SimpleAllocator() {
+ std::lock_guard<std::mutex> g(m_);
+ for (auto& block : blocks_) {
+ aligned_free(block);
+ }
+}
+
+void* SimpleAllocator::allocateHard() {
+ // Allocate a new slab.
+ mem_ = static_cast<uint8_t*>(aligned_malloc(allocSize_, allocSize_));
+ if (!mem_) {
+ std::__throw_bad_alloc();
+ }
+ end_ = mem_ + allocSize_;
+ blocks_.push_back(mem_);
+
+ // Install a pointer to ourselves as the allocator.
+ *reinterpret_cast<SimpleAllocator**>(mem_) = this;
+ static_assert(
+ alignof(std::max_align_t) >= sizeof(SimpleAllocator*),
+ "alignment too small");
+ mem_ += std::min(sz_, alignof(std::max_align_t));
+
+ // New allocation.
+ auto mem = mem_;
+ mem_ += sz_;
+ assert(intptr_t(mem) % 128 != 0);
+ return mem;
+}
+
} // namespace detail
} // namespace folly