Added grow request tracking again. In case an allocation fails due to lack of

contiguous pages, it will request growing even if there are still more than
10% free pages available. Previously that case was not handled anymore and the
allocation would have just failed. Note that this is a pretty rare case, as
there are no "large" allocations happening in either the small or large heap
classes, but only in the huge one for allocations between 128KB and 1MB.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26220 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Lotz 2008-07-02 11:42:35 +00:00
parent 96a152f90d
commit 84c54473eb

View File

@ -137,6 +137,7 @@ static heap_class sHeapClasses[HEAP_CLASS_COUNT] = {
}; };
static heap_allocator *sHeapList[HEAP_CLASS_COUNT]; static heap_allocator *sHeapList[HEAP_CLASS_COUNT];
static heap_allocator *sLastGrowRequest[HEAP_CLASS_COUNT];
static heap_allocator *sGrowHeapList = NULL; static heap_allocator *sGrowHeapList = NULL;
static thread_id sHeapGrowThread = -1; static thread_id sHeapGrowThread = -1;
static sem_id sHeapGrowSem = -1; static sem_id sHeapGrowSem = -1;
@ -1332,8 +1333,11 @@ heap_grow_thread(void *)
while (heap->next) while (heap->next)
heap = heap->next; heap = heap->next;
if (heap_should_grow(heap)) { if (sLastGrowRequest[i] == heap || heap_should_grow(heap)) {
// grow this heap if it makes sense to // grow this heap if it is nearly full or if a grow was
// explicitly requested for this heap (happens when a large
// allocation cannot be fulfilled due to lack of contiguous
// pages)
heap_allocator *newHeap = heap_create_new_heap("additional heap", heap_allocator *newHeap = heap_create_new_heap("additional heap",
HEAP_GROW_SIZE, i); HEAP_GROW_SIZE, i);
if (newHeap != NULL) { if (newHeap != NULL) {
@ -1362,6 +1366,7 @@ heap_init(addr_t base, size_t size)
for (uint32 i = 0; i < HEAP_CLASS_COUNT; i++) { for (uint32 i = 0; i < HEAP_CLASS_COUNT; i++) {
size_t partSize = size * sHeapClasses[i].initial_percentage / 100; size_t partSize = size * sHeapClasses[i].initial_percentage / 100;
sHeapList[i] = heap_attach(base, partSize, i); sHeapList[i] = heap_attach(base, partSize, i);
sLastGrowRequest[i] = sHeapList[i];
base += partSize; base += partSize;
} }
@ -1490,6 +1495,7 @@ memalign(size_t alignment, size_t size)
void *result = heap_memalign(heap, alignment, size, &shouldGrow); void *result = heap_memalign(heap, alignment, size, &shouldGrow);
if (heap->next == NULL && (shouldGrow || result == NULL)) { if (heap->next == NULL && (shouldGrow || result == NULL)) {
// the last heap will or has run out of memory, notify the grower // the last heap will or has run out of memory, notify the grower
sLastGrowRequest[heap_class_for(size)] = heap;
if (result == NULL) { if (result == NULL) {
// urgent request, do the request and wait // urgent request, do the request and wait
switch_sem(sHeapGrowSem, sHeapGrownNotify); switch_sem(sHeapGrowSem, sHeapGrownNotify);