util/HugeAllocator: HugeAllocator() returns WritableBuffer<void>
This commit is contained in:
parent
3e5ce3c92c
commit
b46835e15e
@ -50,12 +50,13 @@ ThreadInputStream::Start()
|
||||
{
|
||||
assert(buffer == nullptr);
|
||||
|
||||
void *p = HugeAllocate(buffer_size);
|
||||
assert(p != nullptr);
|
||||
auto allocation = HugeAllocate(buffer_size);
|
||||
assert(allocation != nullptr);
|
||||
|
||||
HugeForkCow(p, buffer_size, false);
|
||||
HugeForkCow(allocation.data, allocation.size, false);
|
||||
|
||||
buffer = new CircularBuffer<uint8_t>((uint8_t *)p, buffer_size);
|
||||
buffer = new CircularBuffer<uint8_t>((uint8_t *)allocation.data,
|
||||
allocation.size);
|
||||
thread.Start();
|
||||
}
|
||||
|
||||
|
@ -55,7 +55,7 @@ AlignToPageSize(size_t size) noexcept
|
||||
return (size + ps - 1) / ps * ps;
|
||||
}
|
||||
|
||||
void *
|
||||
WritableBuffer<void>
|
||||
HugeAllocate(size_t size)
|
||||
{
|
||||
size = AlignToPageSize(size);
|
||||
@ -73,7 +73,7 @@ HugeAllocate(size_t size)
|
||||
madvise(p, size, MADV_HUGEPAGE);
|
||||
#endif
|
||||
|
||||
return p;
|
||||
return {p, size};
|
||||
}
|
||||
|
||||
void
|
||||
@ -101,7 +101,7 @@ HugeDiscard(void *p, size_t size) noexcept
|
||||
|
||||
#elif defined(WIN32)
|
||||
|
||||
void *
|
||||
WritableBuffer<void>
|
||||
HugeAllocate(size_t size)
|
||||
{
|
||||
// TODO: use MEM_LARGE_PAGES
|
||||
@ -111,7 +111,8 @@ HugeAllocate(size_t size)
|
||||
if (p == nullptr)
|
||||
throw std::bad_alloc();
|
||||
|
||||
return p;
|
||||
// TODO: round size up to the page size
|
||||
return {p, size};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -30,6 +30,7 @@
|
||||
#ifndef HUGE_ALLOCATOR_HXX
|
||||
#define HUGE_ALLOCATOR_HXX
|
||||
|
||||
#include "WritableBuffer.hxx"
|
||||
#include "Compiler.h"
|
||||
|
||||
#include <utility>
|
||||
@ -44,9 +45,12 @@
|
||||
* need it anymore. On the downside, this call is expensive.
|
||||
*
|
||||
* Throws std::bad_alloc on error
|
||||
*
|
||||
* @returns the allocated buffer with a size which may be rounded up
|
||||
* (to the next page size), so callers can take advantage of this
|
||||
* allocation overhead
|
||||
*/
|
||||
gcc_malloc
|
||||
void *
|
||||
WritableBuffer<void>
|
||||
HugeAllocate(size_t size);
|
||||
|
||||
/**
|
||||
@ -77,8 +81,7 @@ HugeDiscard(void *p, size_t size) noexcept;
|
||||
#elif defined(WIN32)
|
||||
#include <windows.h>
|
||||
|
||||
gcc_malloc
|
||||
void *
|
||||
WritableBuffer<void>
|
||||
HugeAllocate(size_t size);
|
||||
|
||||
static inline void
|
||||
@ -104,11 +107,10 @@ HugeDiscard(void *p, size_t size) noexcept
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
gcc_malloc
|
||||
static inline void *
|
||||
WritableBuffer<void>
|
||||
HugeAllocate(size_t size)
|
||||
{
|
||||
return new uint8_t[size];
|
||||
return {new uint8_t[size], size};
|
||||
}
|
||||
|
||||
static inline void
|
||||
@ -134,46 +136,44 @@ HugeDiscard(void *, size_t) noexcept
|
||||
* Automatic huge memory allocation management.
|
||||
*/
|
||||
class HugeAllocation {
|
||||
void *data = nullptr;
|
||||
size_t size;
|
||||
WritableBuffer<void> buffer = nullptr;
|
||||
|
||||
public:
|
||||
HugeAllocation() = default;
|
||||
|
||||
explicit HugeAllocation(size_t _size)
|
||||
:data(HugeAllocate(_size)), size(_size) {}
|
||||
:buffer(HugeAllocate(_size)) {}
|
||||
|
||||
HugeAllocation(HugeAllocation &&src) noexcept
|
||||
:data(std::exchange(src.data, nullptr)), size(src.size) {}
|
||||
:buffer(std::exchange(src.buffer, nullptr)) {}
|
||||
|
||||
~HugeAllocation() {
|
||||
if (data != nullptr)
|
||||
HugeFree(data, size);
|
||||
if (buffer != nullptr)
|
||||
HugeFree(buffer.data, buffer.size);
|
||||
}
|
||||
|
||||
HugeAllocation &operator=(HugeAllocation &&src) noexcept {
|
||||
std::swap(data, src.data);
|
||||
std::swap(size, src.size);
|
||||
std::swap(buffer, src.buffer);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void ForkCow(bool enable) noexcept {
|
||||
HugeForkCow(data, size, enable);
|
||||
HugeForkCow(buffer.data, buffer.size, enable);
|
||||
}
|
||||
|
||||
void Discard() noexcept {
|
||||
HugeDiscard(data, size);
|
||||
HugeDiscard(buffer.data, buffer.size);
|
||||
}
|
||||
|
||||
void reset() noexcept {
|
||||
if (data != nullptr) {
|
||||
HugeFree(data, size);
|
||||
data = nullptr;
|
||||
if (buffer != nullptr) {
|
||||
HugeFree(buffer.data, buffer.size);
|
||||
buffer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void *get() noexcept {
|
||||
return data;
|
||||
return buffer.data;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -72,7 +72,7 @@ class SliceBuffer {
|
||||
public:
|
||||
SliceBuffer(unsigned _count)
|
||||
:n_max(_count),
|
||||
data((Slice *)HugeAllocate(CalcAllocationSize())) {
|
||||
data((Slice *)HugeAllocate(CalcAllocationSize()).data) {
|
||||
assert(n_max > 0);
|
||||
|
||||
HugeForkCow(data, CalcAllocationSize(), false);
|
||||
|
Loading…
Reference in New Issue
Block a user