mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 09:52:27 -04:00
gobj: add alignment support and move semantics to SimpleAllocator
This commit is contained in:
parent
68e7f681f4
commit
f2976b03ec
@ -32,9 +32,9 @@ SimpleAllocator(size_t max_size, Mutex &lock) :
|
|||||||
* pointer.
|
* pointer.
|
||||||
*/
|
*/
|
||||||
SimpleAllocatorBlock *SimpleAllocator::
|
SimpleAllocatorBlock *SimpleAllocator::
|
||||||
alloc(size_t size) {
|
alloc(size_t size, size_t alignment) {
|
||||||
MutexHolder holder(_lock);
|
MutexHolder holder(_lock);
|
||||||
return do_alloc(size);
|
return do_alloc(size, alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -148,6 +148,24 @@ SimpleAllocatorBlock(SimpleAllocator *alloc,
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transfers ownership from the given SimpleAllocatorBlock to this one.
|
||||||
|
*/
|
||||||
|
INLINE SimpleAllocatorBlock::
|
||||||
|
SimpleAllocatorBlock(SimpleAllocatorBlock &&from) :
|
||||||
|
_allocator(from._allocator)
|
||||||
|
{
|
||||||
|
if (_allocator == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MutexHolder holder(_allocator->_lock);
|
||||||
|
_start = from._start;
|
||||||
|
_size = from._size;
|
||||||
|
LinkedListNode::operator = (std::move(from));
|
||||||
|
from._allocator = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The block automatically frees itself when it destructs.
|
* The block automatically frees itself when it destructs.
|
||||||
*/
|
*/
|
||||||
@ -156,6 +174,28 @@ INLINE SimpleAllocatorBlock::
|
|||||||
free();
|
free();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Frees this block and instead takes ownership of the given other block.
|
||||||
|
*/
|
||||||
|
INLINE SimpleAllocatorBlock &SimpleAllocatorBlock::
|
||||||
|
operator = (SimpleAllocatorBlock &&from) {
|
||||||
|
free();
|
||||||
|
|
||||||
|
_allocator = from._allocator;
|
||||||
|
if (_allocator == nullptr) {
|
||||||
|
_start = 0;
|
||||||
|
_size = 0;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
MutexHolder holder(_allocator->_lock);
|
||||||
|
_start = from._start;
|
||||||
|
_size = from._size;
|
||||||
|
LinkedListNode::operator = (std::move(from));
|
||||||
|
from._allocator = nullptr;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Releases the allocated space.
|
* Releases the allocated space.
|
||||||
*/
|
*/
|
||||||
|
@ -13,6 +13,37 @@
|
|||||||
|
|
||||||
#include "simpleAllocator.h"
|
#include "simpleAllocator.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move constructor.
|
||||||
|
*/
|
||||||
|
SimpleAllocator::
|
||||||
|
SimpleAllocator(SimpleAllocator &&from) noexcept :
|
||||||
|
LinkedListNode(std::move(from)),
|
||||||
|
_total_size(from._total_size),
|
||||||
|
_max_size(from._max_size),
|
||||||
|
_contiguous(from._contiguous),
|
||||||
|
_lock(from._lock)
|
||||||
|
{
|
||||||
|
MutexHolder holder(_lock);
|
||||||
|
from._total_size = 0;
|
||||||
|
from._max_size = 0;
|
||||||
|
from._contiguous = 0;
|
||||||
|
|
||||||
|
// We still need to leave the list in a valid state.
|
||||||
|
from._prev = &from;
|
||||||
|
from._next = &from;
|
||||||
|
|
||||||
|
// Change all the blocks to point to the new allocator.
|
||||||
|
LinkedListNode *next = _next;
|
||||||
|
while (next != this) {
|
||||||
|
SimpleAllocatorBlock *block = (SimpleAllocatorBlock *)next;
|
||||||
|
nassertv(block->_allocator == &from);
|
||||||
|
block->_allocator = this;
|
||||||
|
|
||||||
|
next = block->_next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -66,7 +97,7 @@ write(std::ostream &out) const {
|
|||||||
* Assumes the lock is already held.
|
* Assumes the lock is already held.
|
||||||
*/
|
*/
|
||||||
SimpleAllocatorBlock *SimpleAllocator::
|
SimpleAllocatorBlock *SimpleAllocator::
|
||||||
do_alloc(size_t size) {
|
do_alloc(size_t size, size_t alignment) {
|
||||||
if (size > _contiguous) {
|
if (size > _contiguous) {
|
||||||
// Don't even bother.
|
// Don't even bother.
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -86,9 +117,9 @@ do_alloc(size_t size) {
|
|||||||
// Scan until we have reached the last allocated block.
|
// Scan until we have reached the last allocated block.
|
||||||
while (block->_next != this) {
|
while (block->_next != this) {
|
||||||
SimpleAllocatorBlock *next = (SimpleAllocatorBlock *)block->_next;
|
SimpleAllocatorBlock *next = (SimpleAllocatorBlock *)block->_next;
|
||||||
size_t free_size = next->_start - end;
|
size_t start = end + ((alignment - end) % alignment);
|
||||||
if (size <= free_size) {
|
if (start + size <= next->_start) {
|
||||||
SimpleAllocatorBlock *new_block = make_block(end, size);
|
SimpleAllocatorBlock *new_block = make_block(start, size);
|
||||||
nassertr(new_block->get_allocator() == this, nullptr);
|
nassertr(new_block->get_allocator() == this, nullptr);
|
||||||
|
|
||||||
new_block->insert_before(next);
|
new_block->insert_before(next);
|
||||||
@ -103,6 +134,7 @@ do_alloc(size_t size) {
|
|||||||
}
|
}
|
||||||
return new_block;
|
return new_block;
|
||||||
}
|
}
|
||||||
|
size_t free_size = next->_start - end;
|
||||||
if (free_size > best) {
|
if (free_size > best) {
|
||||||
best = free_size;
|
best = free_size;
|
||||||
}
|
}
|
||||||
@ -113,9 +145,9 @@ do_alloc(size_t size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// No free blocks; check for room at the end.
|
// No free blocks; check for room at the end.
|
||||||
size_t free_size = _max_size - end;
|
size_t start = end + ((alignment - end) % alignment);
|
||||||
if (size <= free_size) {
|
if (start + size <= _max_size) {
|
||||||
SimpleAllocatorBlock *new_block = make_block(end, size);
|
SimpleAllocatorBlock *new_block = make_block(start, size);
|
||||||
nassertr(new_block->get_allocator() == this, nullptr);
|
nassertr(new_block->get_allocator() == this, nullptr);
|
||||||
|
|
||||||
new_block->insert_before(this);
|
new_block->insert_before(this);
|
||||||
@ -131,6 +163,7 @@ do_alloc(size_t size) {
|
|||||||
return new_block;
|
return new_block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t free_size = _max_size - end;
|
||||||
if (free_size > best) {
|
if (free_size > best) {
|
||||||
best = free_size;
|
best = free_size;
|
||||||
}
|
}
|
||||||
|
@ -29,9 +29,10 @@ class SimpleAllocatorBlock;
|
|||||||
class EXPCL_PANDA_GOBJ SimpleAllocator : public LinkedListNode {
|
class EXPCL_PANDA_GOBJ SimpleAllocator : public LinkedListNode {
|
||||||
PUBLISHED:
|
PUBLISHED:
|
||||||
INLINE explicit SimpleAllocator(size_t max_size, Mutex &lock);
|
INLINE explicit SimpleAllocator(size_t max_size, Mutex &lock);
|
||||||
|
SimpleAllocator(SimpleAllocator &&from) noexcept;
|
||||||
virtual ~SimpleAllocator();
|
virtual ~SimpleAllocator();
|
||||||
|
|
||||||
INLINE SimpleAllocatorBlock *alloc(size_t size);
|
INLINE SimpleAllocatorBlock *alloc(size_t size, size_t alignment=1);
|
||||||
|
|
||||||
INLINE bool is_empty() const;
|
INLINE bool is_empty() const;
|
||||||
INLINE size_t get_total_size() const;
|
INLINE size_t get_total_size() const;
|
||||||
@ -45,7 +46,7 @@ PUBLISHED:
|
|||||||
void write(std::ostream &out) const;
|
void write(std::ostream &out) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SimpleAllocatorBlock *do_alloc(size_t size);
|
SimpleAllocatorBlock *do_alloc(size_t size, size_t alignment=1);
|
||||||
INLINE bool do_is_empty() const;
|
INLINE bool do_is_empty() const;
|
||||||
|
|
||||||
virtual SimpleAllocatorBlock *make_block(size_t start, size_t size);
|
virtual SimpleAllocatorBlock *make_block(size_t start, size_t size);
|
||||||
@ -91,6 +92,14 @@ protected:
|
|||||||
INLINE SimpleAllocatorBlock(SimpleAllocator *alloc,
|
INLINE SimpleAllocatorBlock(SimpleAllocator *alloc,
|
||||||
size_t start, size_t size);
|
size_t start, size_t size);
|
||||||
|
|
||||||
|
public:
|
||||||
|
SimpleAllocatorBlock() = default;
|
||||||
|
SimpleAllocatorBlock(const SimpleAllocatorBlock ©) = delete;
|
||||||
|
INLINE SimpleAllocatorBlock(SimpleAllocatorBlock &&from);
|
||||||
|
|
||||||
|
SimpleAllocatorBlock &operator = (const SimpleAllocatorBlock ©) = delete;
|
||||||
|
INLINE SimpleAllocatorBlock &operator = (SimpleAllocatorBlock &&from);
|
||||||
|
|
||||||
PUBLISHED:
|
PUBLISHED:
|
||||||
INLINE ~SimpleAllocatorBlock();
|
INLINE ~SimpleAllocatorBlock();
|
||||||
INLINE void free();
|
INLINE void free();
|
||||||
@ -114,9 +123,9 @@ protected:
|
|||||||
INLINE bool do_realloc(size_t size);
|
INLINE bool do_realloc(size_t size);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SimpleAllocator *_allocator;
|
SimpleAllocator *_allocator = nullptr;
|
||||||
size_t _start;
|
size_t _start = 0;
|
||||||
size_t _size;
|
size_t _size = 0;
|
||||||
|
|
||||||
friend class SimpleAllocator;
|
friend class SimpleAllocator;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user