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