|
|
@@ -23,14 +23,30 @@
|
|
|
// Description:
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
INLINE SimpleAllocator::
|
|
|
-SimpleAllocator(size_t max_size) :
|
|
|
+SimpleAllocator(size_t max_size, Mutex &lock) :
|
|
|
LinkedListNode(true),
|
|
|
_total_size(0),
|
|
|
_max_size(max_size),
|
|
|
- _contiguous(max_size)
|
|
|
+ _contiguous(max_size),
|
|
|
+ _lock(lock)
|
|
|
{
|
|
|
}
|
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: SimpleAllocator::alloc
|
|
|
+// Access: Published
|
|
|
+// Description: Allocates a new block. Returns NULL if a block of the
|
|
|
+// requested size cannot be allocated.
|
|
|
+//
|
|
|
+// To free the allocated block, call block->free(), or
|
|
|
+// simply delete the block pointer.
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+SimpleAllocatorBlock *SimpleAllocator::
|
|
|
+alloc(size_t size) {
|
|
|
+ MutexHolder holder(_lock);
|
|
|
+ return do_alloc(size);
|
|
|
+}
|
|
|
+
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
// Function: SimpleAllocator::is_empty
|
|
|
// Access: Published
|
|
|
@@ -39,7 +55,8 @@ SimpleAllocator(size_t max_size) :
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
INLINE bool SimpleAllocator::
|
|
|
is_empty() const {
|
|
|
- return (_next == this);
|
|
|
+ MutexHolder holder(_lock);
|
|
|
+ return do_is_empty();
|
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
@@ -49,6 +66,7 @@ is_empty() const {
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
INLINE size_t SimpleAllocator::
|
|
|
get_total_size() const {
|
|
|
+ MutexHolder holder(_lock);
|
|
|
return _total_size;
|
|
|
}
|
|
|
|
|
|
@@ -59,6 +77,7 @@ get_total_size() const {
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
INLINE size_t SimpleAllocator::
|
|
|
get_max_size() const {
|
|
|
+ MutexHolder holder(_lock);
|
|
|
return _max_size;
|
|
|
}
|
|
|
|
|
|
@@ -71,6 +90,7 @@ get_max_size() const {
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
INLINE void SimpleAllocator::
|
|
|
set_max_size(size_t max_size) {
|
|
|
+ MutexHolder holder(_lock);
|
|
|
_max_size = max_size;
|
|
|
}
|
|
|
|
|
|
@@ -86,6 +106,7 @@ set_max_size(size_t max_size) {
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
INLINE size_t SimpleAllocator::
|
|
|
get_contiguous() const {
|
|
|
+ MutexHolder holder(_lock);
|
|
|
return _contiguous;
|
|
|
}
|
|
|
|
|
|
@@ -97,15 +118,31 @@ get_contiguous() const {
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
INLINE SimpleAllocatorBlock *SimpleAllocator::
|
|
|
get_first_block() const {
|
|
|
+ MutexHolder holder(_lock);
|
|
|
return (_next == this) ? (SimpleAllocatorBlock *)NULL : (SimpleAllocatorBlock *)_next;
|
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
-// Function: SimpleAllocator::increase_contiguous
|
|
|
+// Function: SimpleAllocator::do_is_empty
|
|
|
+// Access: Protected
|
|
|
+// Description: Returns true if there are no blocks allocated on this
|
|
|
+// page, or false if there is at least one.
|
|
|
+//
|
|
|
+// Assumes the lock is already held.
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+INLINE bool SimpleAllocator::
|
|
|
+do_is_empty() const {
|
|
|
+ return (_next == this);
|
|
|
+}
|
|
|
+
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: SimpleAllocator::mark_contiguous
|
|
|
// Access: Protected
|
|
|
// Description: Some space has been made available following the
|
|
|
// indicated block. Increase the contiguous space
|
|
|
// accordingly.
|
|
|
+//
|
|
|
+// Assumes the lock is already held.
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
INLINE void SimpleAllocator::
|
|
|
mark_contiguous(const LinkedListNode *block) {
|
|
|
@@ -119,10 +156,11 @@ mark_contiguous(const LinkedListNode *block) {
|
|
|
space = ((SimpleAllocatorBlock *)_next)->get_start();
|
|
|
}
|
|
|
} else {
|
|
|
- space = ((SimpleAllocatorBlock *)block)->get_max_size() - ((SimpleAllocatorBlock *)block)->get_size();
|
|
|
+ space = ((SimpleAllocatorBlock *)block)->do_get_max_size() - ((SimpleAllocatorBlock *)block)->get_size();
|
|
|
}
|
|
|
if (space > _contiguous) {
|
|
|
_contiguous = space;
|
|
|
+ changed_contiguous();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -160,11 +198,8 @@ INLINE SimpleAllocatorBlock::
|
|
|
INLINE void SimpleAllocatorBlock::
|
|
|
free() {
|
|
|
if (_allocator != (SimpleAllocator *)NULL) {
|
|
|
- _allocator->_total_size -= _size;
|
|
|
- LinkedListNode *prev = _prev;
|
|
|
- remove_from_list();
|
|
|
- _allocator->mark_contiguous(prev);
|
|
|
- _allocator = NULL;
|
|
|
+ MutexHolder holder(_allocator->_lock);
|
|
|
+ do_free();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -223,10 +258,68 @@ is_free() const {
|
|
|
INLINE size_t SimpleAllocatorBlock::
|
|
|
get_max_size() const {
|
|
|
nassertr(_allocator != (SimpleAllocator *)NULL, 0);
|
|
|
+ MutexHolder holder(_allocator->_lock);
|
|
|
+ return do_get_max_size();
|
|
|
+}
|
|
|
+
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: SimpleAllocatorBlock::realloc
|
|
|
+// Access: Published
|
|
|
+// Description: Changes the size of this block to the specified size.
|
|
|
+// Returns true if the change is accepted, false if
|
|
|
+// there was not enough room.
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+INLINE bool SimpleAllocatorBlock::
|
|
|
+realloc(size_t size) {
|
|
|
+ nassertr(_allocator != (SimpleAllocator *)NULL, false);
|
|
|
+ MutexHolder holder(_allocator->_lock);
|
|
|
+ return do_realloc(size);
|
|
|
+}
|
|
|
+
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: SimpleAllocatorBlock::get_next_block
|
|
|
+// Access: Published
|
|
|
+// Description: Returns a pointer to the next allocated block in the
|
|
|
+// chain, or NULL if there are no more allocated blocks.
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+INLINE SimpleAllocatorBlock *SimpleAllocatorBlock::
|
|
|
+get_next_block() const {
|
|
|
+ nassertr(_allocator != (SimpleAllocator *)NULL, NULL);
|
|
|
+ MutexHolder holder(_allocator->_lock);
|
|
|
+ return (_next == _allocator) ? (SimpleAllocatorBlock *)NULL : (SimpleAllocatorBlock *)_next;
|
|
|
+}
|
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: SimpleAllocatorBlock::do_free
|
|
|
+// Access: Protected
|
|
|
+// Description: Releases the allocated space.
|
|
|
+//
|
|
|
+// Assumes the lock is already held.
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+INLINE void SimpleAllocatorBlock::
|
|
|
+do_free() {
|
|
|
+ nassertv(_allocator != (SimpleAllocator *)NULL);
|
|
|
+
|
|
|
+ _allocator->_total_size -= _size;
|
|
|
+ LinkedListNode *prev = _prev;
|
|
|
+ remove_from_list();
|
|
|
+ _allocator->mark_contiguous(prev);
|
|
|
+ _allocator = NULL;
|
|
|
+}
|
|
|
+
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: SimpleAllocatorBlock::do_get_max_size
|
|
|
+// Access: Protected
|
|
|
+// Description: Returns the maximum size this block can be
|
|
|
+// reallocated to, as limited by the following block.
|
|
|
+//
|
|
|
+// Assumes the lock is already held.
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+INLINE size_t SimpleAllocatorBlock::
|
|
|
+do_get_max_size() const {
|
|
|
size_t end;
|
|
|
if (_next == _allocator) {
|
|
|
- end = _allocator->get_max_size();
|
|
|
+ end = _allocator->_max_size;
|
|
|
} else {
|
|
|
end = ((SimpleAllocatorBlock *)_next)->_start;
|
|
|
}
|
|
|
@@ -234,15 +327,17 @@ get_max_size() const {
|
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
-// Function: SimpleAllocatorBlock::realloc
|
|
|
-// Access: Published
|
|
|
+// Function: SimpleAllocatorBlock::do_realloc
|
|
|
+// Access: Protected
|
|
|
// Description: Changes the size of this block to the specified size.
|
|
|
// Returns true if the change is accepted, false if
|
|
|
// there was not enough room.
|
|
|
+//
|
|
|
+// Assumes the lock is already held.
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
INLINE bool SimpleAllocatorBlock::
|
|
|
-realloc(size_t size) {
|
|
|
- if (size > get_max_size()) {
|
|
|
+do_realloc(size_t size) {
|
|
|
+ if (size > do_get_max_size()) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
@@ -259,14 +354,3 @@ realloc(size_t size) {
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
-
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-// Function: SimpleAllocatorBlock::get_next_block
|
|
|
-// Access: Published
|
|
|
-// Description: Returns a pointer to the next allocated block in the
|
|
|
-// chain, or NULL if there are no more allocated blocks.
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-INLINE SimpleAllocatorBlock *SimpleAllocatorBlock::
|
|
|
-get_next_block() const {
|
|
|
- return (_next == _allocator) ? (SimpleAllocatorBlock *)NULL : (SimpleAllocatorBlock *)_next;
|
|
|
-}
|