Changeset 18 for trunk/kernel/mm/khm.c
- Timestamp:
- Jun 3, 2017, 4:42:49 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/mm/khm.c
r14 r18 1 1 /* 2 2 * khm.c - kernel heap manager implementation. 3 * 3 * 4 4 * Authors Ghassan Almaless (2008,2009,2010,2011,2012) 5 5 * Alain Greiner (2016) … … 44 44 45 45 // initialize lock 46 spinlock_init( &khm->lock ); 47 48 // compute kernel heap size46 spinlock_init( &khm->lock ); 47 48 // compute kernel heap size 49 49 intptr_t heap_size = (1 << CONFIG_PPM_HEAP_ORDER) << CONFIG_PPM_PAGE_SHIFT; 50 50 51 // get kernel heap base from PPM 51 // get kernel heap base from PPM 52 52 page_t * page = ppm_alloc_pages( CONFIG_PPM_HEAP_ORDER ); 53 53 void * heap_base = ppm_page2base( page ); … … 65 65 66 66 ///////////////////////////////// 67 void * khm_alloc( khm_t * khm, 67 void * khm_alloc( khm_t * khm, 68 68 uint32_t size ) 69 69 { 70 khm_block_t * current; 70 khm_block_t * current; 71 71 khm_block_t * next; 72 72 uint32_t effective_size; … … 78 78 // get lock protecting heap 79 79 spinlock_lock( &khm->lock ); 80 81 // define a starting block to scan existing blocks 80 81 // define a starting block to scan existing blocks 82 82 if( ((khm_block_t*)khm->next)->size < effective_size ) current = (khm_block_t*)khm->base; 83 83 else current = (khm_block_t*)khm->next; 84 84 85 85 // scan all existing blocks to find a large enough free block 86 while( current->busy || (current->size < effective_size)) 86 while( current->busy || (current->size < effective_size)) 87 87 { 88 88 // get next block pointer 89 89 current = (khm_block_t*)((char*)current + current->size); 90 90 91 91 if( (intptr_t)current >= (khm->base + khm->size) ) // heap full 92 92 { 93 93 spinlock_unlock(&khm->lock); 94 94 95 printk("\n[ERROR] in %s : failed to allocate block of size %d\n", 95 printk("\n[ERROR] in %s : failed to allocate block of size %d\n", 96 96 __FUNCTION__ , effective_size ); 97 97 return NULL; … … 133 133 khm_block_t * current; 134 134 khm_block_t * next; 135 135 136 136 if(ptr == NULL) return; 137 137 138 138 current = (khm_block_t *)((char*)ptr - sizeof(khm_block_t)); 139 139 140 140 // get lock protecting heap 141 141 spinlock_lock(&khm->lock); 142 142 143 // release block 143 // release block 144 144 current->busy = 0; 145 145 146 146 // try to merge released block with the next 147 147 while ( 1 ) 148 { 148 { 149 149 next = (khm_block_t*)((char*)current + current->size); 150 150 if ( ((intptr_t)next >= (khm->base + khm->size)) || (next->busy == 1) ) break; … … 153 153 154 154 if( (intptr_t)current < khm->next ) khm->next = (intptr_t)current; 155 155 156 156 // release lock protecting heap 157 157 spinlock_unlock( &khm->lock );
Note: See TracChangeset
for help on using the changeset viewer.