diff options
-rw-r--r-- | src/include/kernel/heapmgr.H | 55 | ||||
-rw-r--r-- | src/kernel/heapmgr.C | 12 |
2 files changed, 36 insertions, 31 deletions
diff --git a/src/include/kernel/heapmgr.H b/src/include/kernel/heapmgr.H index 56652ea66..cee0517f0 100644 --- a/src/include/kernel/heapmgr.H +++ b/src/include/kernel/heapmgr.H @@ -1,25 +1,25 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/include/kernel/heapmgr.H $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2010 - 2011 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/include/kernel/heapmgr.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2010,2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ #ifndef __KERNEL_HEAPMGR_H #define __KERNEL_HEAPMGR_H @@ -40,7 +40,7 @@ void kernel_execute_decrementer(); * The small heap increases one page at a time as allocations are needed. * A 4k pages is initially divided into buckes of size 3728,336, and 32. * Pages can't be recovered once assinged to the small heap.</p> - * + * * <p>Anthing larger than 3720 goes into the large allocation heap. * Memory in the large allocation heap are assigned as integral pages. * When memory is released from the large allocation heap, it is returned @@ -134,10 +134,11 @@ class HeapManager { struct { - bool free:1; //!< Is chunck free - uint64_t bucket:63; //!< Which bucket this chunk belongs to + bool free:1; //!< Is chunk free + bool coalesce:1; //!< Is chunk being coalesced + uint64_t bucket:62; //!< Which bucket this chunk belongs to } PACKED; - + chunk_t* next; //!< Next chunk (for unallocated chunks only) }; @@ -150,7 +151,7 @@ class HeapManager size_t page_count; //!< Number of pages used big_chunk_t * next; //!< Next allocation - big_chunk_t(void * i_ptr, size_t i_pages) + big_chunk_t(void * i_ptr, size_t i_pages) : addr(i_ptr), page_count(i_pages), next(NULL) {} }; diff --git a/src/kernel/heapmgr.C b/src/kernel/heapmgr.C index 5518a96f8..d2df127e9 100644 --- a/src/kernel/heapmgr.C +++ b/src/kernel/heapmgr.C @@ -330,7 +330,10 @@ void HeapManager::_coalesce() chunk = NULL; while(NULL != (chunk = first_chunk[bucket].pop())) { + kassert(chunk->free); + chunk->next = head; + chunk->coalesce = true; head = chunk; } } @@ -351,7 +354,7 @@ void HeapManager::_coalesce() { // This chunk might already be combined with a chunk earlier // in the loop. - if(!chunk->free) + if((!chunk->coalesce) || (!chunk->free)) { break; } @@ -370,7 +373,7 @@ void HeapManager::_coalesce() } // Cannot merge if buddy is not free. - if (!buddy->free) + if ((!buddy->free) || (!buddy->coalesce)) { break; } @@ -387,7 +390,7 @@ void HeapManager::_coalesce() } // Do merge. - buddy->free = false; + buddy->free = buddy->coalesce = false; chunk->bucket = newBucket; incrementChunk = false; mergedChunks = true; @@ -407,7 +410,7 @@ void HeapManager::_coalesce() chunk = head; while (NULL != chunk) { - if (chunk->free) + if ((chunk->free) && (chunk->coalesce)) { chunk_t* temp = chunk->next; chunk->next = newHead; @@ -434,6 +437,7 @@ void HeapManager::_coalesce() { chunk_t * temp = chunk->next; + chunk->coalesce = false; push_bucket(chunk,chunk->bucket); ++cv_free_chunks; |