* Use a singly linked list for the deferred free entries.
* Added deferred_delete() that takes a DeferredDeletable and deletes it asynchronously. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28285 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -75,6 +75,9 @@ status_t heap_init_post_thread();
|
|||||||
|
|
||||||
#include <new>
|
#include <new>
|
||||||
|
|
||||||
|
#include <util/SinglyLinkedList.h>
|
||||||
|
|
||||||
|
|
||||||
static const struct nogrow_t {
|
static const struct nogrow_t {
|
||||||
} nogrow = {};
|
} nogrow = {};
|
||||||
|
|
||||||
@@ -84,6 +87,16 @@ operator new(size_t size, const nogrow_t& nogrow) throw()
|
|||||||
return malloc_nogrow(size);
|
return malloc_nogrow(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class DeferredDeletable : public SinglyLinkedListLinkImpl<DeferredDeletable> {
|
||||||
|
public:
|
||||||
|
virtual ~DeferredDeletable();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void deferred_delete(DeferredDeletable* deletable);
|
||||||
|
|
||||||
|
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
#include <thread.h>
|
#include <thread.h>
|
||||||
#include <tracing.h>
|
#include <tracing.h>
|
||||||
#include <util/AutoLock.h>
|
#include <util/AutoLock.h>
|
||||||
#include <util/DoublyLinkedList.h>
|
|
||||||
#include <vm.h>
|
#include <vm.h>
|
||||||
|
|
||||||
|
|
||||||
@@ -124,9 +123,11 @@ typedef struct area_allocation_info_s {
|
|||||||
void * allocation_base;
|
void * allocation_base;
|
||||||
} area_allocation_info;
|
} area_allocation_info;
|
||||||
|
|
||||||
struct DeferredFreeListEntry : DoublyLinkedListLinkImpl<DeferredFreeListEntry> {
|
struct DeferredFreeListEntry : SinglyLinkedListLinkImpl<DeferredFreeListEntry> {
|
||||||
};
|
};
|
||||||
typedef DoublyLinkedList<DeferredFreeListEntry> DeferredFreeList;
|
|
||||||
|
typedef SinglyLinkedList<DeferredFreeListEntry> DeferredFreeList;
|
||||||
|
typedef SinglyLinkedList<DeferredDeletable> DeferredDeletableList;
|
||||||
|
|
||||||
// Heap class configuration
|
// Heap class configuration
|
||||||
#define HEAP_CLASS_COUNT 3
|
#define HEAP_CLASS_COUNT 3
|
||||||
@@ -173,6 +174,7 @@ static sem_id sHeapGrownNotify = -1;
|
|||||||
static bool sAddGrowHeap = false;
|
static bool sAddGrowHeap = false;
|
||||||
|
|
||||||
static DeferredFreeList sDeferredFreeList;
|
static DeferredFreeList sDeferredFreeList;
|
||||||
|
static DeferredDeletableList sDeferredDeletableList;
|
||||||
static spinlock sDeferredFreeListLock;
|
static spinlock sDeferredFreeListLock;
|
||||||
|
|
||||||
|
|
||||||
@@ -1610,7 +1612,7 @@ heap_class_for(size_t size)
|
|||||||
static void
|
static void
|
||||||
deferred_deleter(void *arg, int iteration)
|
deferred_deleter(void *arg, int iteration)
|
||||||
{
|
{
|
||||||
// move entries to on-stack list
|
// move entries and deletables to on-stack lists
|
||||||
InterruptsSpinLocker locker(sDeferredFreeListLock);
|
InterruptsSpinLocker locker(sDeferredFreeListLock);
|
||||||
if (sDeferredFreeList.IsEmpty())
|
if (sDeferredFreeList.IsEmpty())
|
||||||
return;
|
return;
|
||||||
@@ -1618,11 +1620,18 @@ deferred_deleter(void *arg, int iteration)
|
|||||||
DeferredFreeList entries;
|
DeferredFreeList entries;
|
||||||
entries.MoveFrom(&sDeferredFreeList);
|
entries.MoveFrom(&sDeferredFreeList);
|
||||||
|
|
||||||
|
DeferredDeletableList deletables;
|
||||||
|
deletables.MoveFrom(&sDeferredDeletableList);
|
||||||
|
|
||||||
locker.Unlock();
|
locker.Unlock();
|
||||||
|
|
||||||
// free the entries
|
// free the entries
|
||||||
while (DeferredFreeListEntry* entry = entries.RemoveHead())
|
while (DeferredFreeListEntry* entry = entries.RemoveHead())
|
||||||
free(entry);
|
free(entry);
|
||||||
|
|
||||||
|
// delete the deletables
|
||||||
|
while (DeferredDeletable* deletable = deletables.RemoveHead())
|
||||||
|
delete deletable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2035,7 +2044,6 @@ deferred_free(void* block)
|
|||||||
if (block == NULL)
|
if (block == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// TODO: Use SinglyLinkedList, so that we only need sizeof(void*).
|
|
||||||
DeferredFreeListEntry* entry = new(block) DeferredFreeListEntry;
|
DeferredFreeListEntry* entry = new(block) DeferredFreeListEntry;
|
||||||
|
|
||||||
InterruptsSpinLocker _(sDeferredFreeListLock);
|
InterruptsSpinLocker _(sDeferredFreeListLock);
|
||||||
@@ -2078,3 +2086,19 @@ malloc_referenced_release(void* data)
|
|||||||
if (atomic_add(referencedData, -1) < 1)
|
if (atomic_add(referencedData, -1) < 1)
|
||||||
free(referencedData);
|
free(referencedData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DeferredDeletable::~DeferredDeletable()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
deferred_delete(DeferredDeletable* deletable)
|
||||||
|
{
|
||||||
|
if (deletable == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
InterruptsSpinLocker _(sDeferredFreeListLock);
|
||||||
|
sDeferredDeletableList.Add(deletable);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user