Added deferred_free() function, that can be used to free allocations
in code that has interrupts disabled. The chunks of memories are queued and free()d periodically by a kernel daemon. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24332 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
45eb999ec8
commit
c1de3c34b3
@ -24,6 +24,8 @@ extern "C" {
|
|||||||
|
|
||||||
void *memalign(size_t alignment, size_t size);
|
void *memalign(size_t alignment, size_t size);
|
||||||
|
|
||||||
|
void deferred_free(void* block);
|
||||||
|
|
||||||
status_t heap_init(addr_t heapBase, size_t heapSize);
|
status_t heap_init(addr_t heapBase, size_t heapSize);
|
||||||
status_t heap_init_post_sem();
|
status_t heap_init_post_sem();
|
||||||
status_t heap_init_post_thread();
|
status_t heap_init_post_thread();
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
#include <team.h>
|
#include <team.h>
|
||||||
#include <thread.h>
|
#include <thread.h>
|
||||||
#include <tracing.h>
|
#include <tracing.h>
|
||||||
|
#include <util/AutoLock.h>
|
||||||
|
#include <util/DoublyLinkedList.h>
|
||||||
#include <vm.h>
|
#include <vm.h>
|
||||||
|
|
||||||
//#define TRACE_HEAP
|
//#define TRACE_HEAP
|
||||||
@ -81,6 +83,10 @@ typedef struct heap_allocator_s {
|
|||||||
heap_allocator_s * next;
|
heap_allocator_s * next;
|
||||||
} heap_allocator;
|
} heap_allocator;
|
||||||
|
|
||||||
|
struct DeferredFreeListEntry : DoublyLinkedListLinkImpl<DeferredFreeListEntry> {
|
||||||
|
};
|
||||||
|
typedef DoublyLinkedList<DeferredFreeListEntry> DeferredFreeList;
|
||||||
|
|
||||||
static heap_allocator *sHeapList = NULL;
|
static heap_allocator *sHeapList = NULL;
|
||||||
static heap_allocator *sLastGrowRequest = NULL;
|
static heap_allocator *sLastGrowRequest = NULL;
|
||||||
static heap_allocator *sGrowHeap = NULL;
|
static heap_allocator *sGrowHeap = NULL;
|
||||||
@ -88,6 +94,10 @@ static thread_id sHeapGrowThread = -1;
|
|||||||
static sem_id sHeapGrowSem = -1;
|
static sem_id sHeapGrowSem = -1;
|
||||||
static sem_id sHeapGrownNotify = -1;
|
static sem_id sHeapGrownNotify = -1;
|
||||||
|
|
||||||
|
static DeferredFreeList sDeferredFreeList;
|
||||||
|
static spinlock sDeferredFreeListLock;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - Tracing
|
// #pragma mark - Tracing
|
||||||
|
|
||||||
@ -962,6 +972,25 @@ heap_realloc(heap_allocator *heap, void *address, void **newAddress,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
deferred_deleter(void *arg, int iteration)
|
||||||
|
{
|
||||||
|
// move entries to on-stack list
|
||||||
|
InterruptsSpinLocker locker(sDeferredFreeListLock);
|
||||||
|
if (sDeferredFreeList.IsEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
DeferredFreeList entries;
|
||||||
|
entries.MoveFrom(&sDeferredFreeList);
|
||||||
|
|
||||||
|
locker.Unlock();
|
||||||
|
|
||||||
|
// free the entries
|
||||||
|
while (DeferredFreeListEntry* entry = entries.RemoveHead())
|
||||||
|
free(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
@ -1092,6 +1121,9 @@ heap_init_post_thread()
|
|||||||
return sHeapGrowThread;
|
return sHeapGrowThread;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (register_kernel_daemon(deferred_deleter, NULL, 50) != B_OK)
|
||||||
|
panic("heap_init_post_thread(): failed to init deferred deleter");
|
||||||
|
|
||||||
send_signal_etc(sHeapGrowThread, SIGCONT, B_DO_NOT_RESCHEDULE);
|
send_signal_etc(sHeapGrowThread, SIGCONT, B_DO_NOT_RESCHEDULE);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@ -1236,3 +1268,17 @@ calloc(size_t numElements, size_t size)
|
|||||||
|
|
||||||
return address;
|
return address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
deferred_free(void* block)
|
||||||
|
{
|
||||||
|
if (block == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// TODO: Use SinglyLinkedList, so that we only need sizeof(void*).
|
||||||
|
DeferredFreeListEntry* entry = new(block) DeferredFreeListEntry;
|
||||||
|
|
||||||
|
InterruptsSpinLocker _(sDeferredFreeListLock);
|
||||||
|
sDeferredFreeList.Add(entry);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user