#include <const.h>
#include <arch/i386.h>
#include <arch/mem.h>
#include <arch/paging.h>
#include <kernel/console.h>
#include <kernel/kernel_map.h>
#include <kernel/keyboard.h>
#include <kernel/task.h>
#include <kernel/kmalloc.h>
Go to the source code of this file.
Functions | |||||||
void | kmalloc_init () | ||||||
Initialize the kernel virtual memory area. | |||||||
void * | kmalloc (size_t size) | ||||||
Allocate a memory block from the kernel memory area. This is a best-fit like allocator.
| |||||||
void | deallocate (mem_block_t *ptr) | ||||||
Try to release physical frames occupied by the freed block.
| |||||||
void | kfree (void *ptr) | ||||||
Frees the memory space pointed by ptr, which must have been returned by a previous call to kmalloc(size_t size).
| |||||||
int | mem_sizeof (void *ptr) | ||||||
Return the size of the pointer ptr passed as argument.
| |||||||
void * | kmemalign (size_t alignment, size_t size) | ||||||
Allocate some memory aligned to a boundary.
| |||||||
void | dump_memory_map () | ||||||
This is a routine for debug only. It prints all the memory block headers.
|
Definition in file kmalloc.c.
|
Try to release physical frames occupied by the freed block.
Definition at line 202 of file kmalloc.c.
00203 { 00204 dword start = PAGE_ALIGN_UP((dword)((void *)ptr + sizeof(mem_block_t))); 00205 dword end = PAGE_ALIGN((dword)((void *)ptr + sizeof(mem_block_t) + ptr->size)); 00206 00207 while(start < end) 00208 { 00209 if (*ADDR_TO_PDE(start) != NULL) 00210 { 00211 delete_page(start); 00212 start += PAGE_SIZE; 00213 } 00214 else 00215 start = PAGE_DIR_ALIGN_UP(start); 00216 } 00217 } |
|
This is a routine for debug only. It prints all the memory block headers.
Definition at line 358 of file kmalloc.c.
00359 { 00360 mem_block_t *p = (mem_block_t *)K_HEAP_START; 00361 00362 for(;;) 00363 { 00364 kprintf( 00365 "\n\rp = %#010x" 00366 "\n\rp->magic = %s" 00367 "\n\rp->flags = %#010x" 00368 "\n\rp->size = %u" 00369 "\n\rp->owner = %i\n\r", 00370 (dword)p + sizeof(mem_block_t), 00371 (byte *)p->magic, 00372 p->flags, 00373 p->size, 00374 p->owner); 00375 00376 p = (void *)p + p->size + sizeof(mem_block_t); 00377 00378 if (p >= (mem_block_t *)K_HEAP_END) break; 00379 00380 // Wait for a key... // 00381 if (kgetchar() == CTRL_C) break; 00382 } 00383 } |
|
Frees the memory space pointed by ptr, which must have been returned by a previous call to kmalloc(size_t size).
Definition at line 223 of file kmalloc.c.
00224 { 00225 mem_block_t *p, *p2; 00226 dword IF = GET_IF(); 00227 00228 if (ptr == NULL) return; 00229 00230 disable(); 00231 00232 // Point to the header // 00233 p = (void *)ptr - sizeof(mem_block_t); 00234 00235 if (p->magic != M_MAGIC) return; // Is the process crazy?! :) // 00236 if (p->flags != M_ALLOC) return; // Crazy again?! :) // 00237 00238 // Free the block // 00239 p->flags = M_FREE; 00240 p->owner = NULL; 00241 00242 // Try to combine the block wih the next one... // 00243 p2 = (void *)p + p->size + sizeof(mem_block_t); 00244 00245 if (p2 < (mem_block_t *)K_HEAP_END) 00246 if (p2->flags == M_FREE) 00247 { 00248 // Let's merge the two blocks! // 00249 p->size += p2->size + sizeof(mem_block_t); 00250 p2->magic = NULL; 00251 } 00252 00253 // Try to combine the block with the previous one... // 00254 if (p != (mem_block_t *)K_HEAP_START) 00255 { 00256 // Find the previous block // 00257 p2 = (void *)K_HEAP_START; 00258 for(;;) 00259 { 00260 if (((void *)p2 + p2->size + sizeof(mem_block_t)) == p) 00261 { 00262 // Block found! // 00263 // Check if it's a free block // 00264 if (p2->flags == M_FREE) 00265 { 00266 // Let's merge the two blocks! // 00267 p2->size += (p->size + sizeof(mem_block_t)); 00268 p->magic = NULL; 00269 p = p2; 00270 } 00271 break; 00272 } 00273 p2 = (void *)p2 + p2->size + sizeof(mem_block_t); 00274 } 00275 } 00276 // Release the physical space occupied by the block // 00277 deallocate(p); 00278 00279 SET_IF(IF); 00280 } |
|
Allocate a memory block from the kernel memory area. This is a best-fit like allocator.
Definition at line 45 of file kmalloc.c.
00046 { 00047 mem_block_t *p, *p_best=NULL; 00048 dword IF = GET_IF(); 00049 00050 if (!size) return NULL; // Is the process crazy?! :-) // 00051 00052 disable(); 00053 00054 // Round the size up to sizeof(mem_block_t); the // 00055 // sizeof(mem_block_t) is the unit of allocation. // 00056 size = ( size & -((uint32_t)sizeof(mem_block_t)) ) + sizeof(mem_block_t); 00057 00058 // Explore the heap for the best-fit hole // 00059 p=(mem_block_t *)K_HEAP_START; 00060 while(p < (mem_block_t *)K_HEAP_END) 00061 { 00062 // Find a free block // 00063 if (p->flags == M_FREE) 00064 { 00065 // This block is free... let's proceed // 00066 if (p->size == size) 00067 { 00068 // Best fit block found! You're lucky! // 00069 p_best = p; 00070 break; 00071 } 00072 if (p->size > size) 00073 { 00074 // The hole is bigger than size... // 00075 // ...check if it's the best-fit hole! // 00076 if (p_best==NULL) 00077 p_best = p; 00078 else 00079 if (p_best->size > p->size) 00080 p_best = p; 00081 } 00082 } 00083 // Examine the next memory block // 00084 p = (void *)p+p->size+sizeof(mem_block_t); 00085 } 00086 00087 // Have you found a free block?! // 00088 if (p_best == NULL) 00089 { 00090 // No free memory :( // 00091 SET_IF(IF); 00092 return NULL; 00093 } 00094 00095 // Found, now allocate it! // 00096 p_best->magic = M_MAGIC; 00097 p_best->flags = M_ALLOC; 00098 p_best->owner = get_pid(); 00099 00100 if (p_best->size == size) 00101 { 00102 p_best = (void *)p_best + sizeof(mem_block_t); 00103 SET_IF(IF); 00104 // The block cover the size perfectly // 00105 return ((void *)p_best); 00106 } 00107 00108 // Otherwise split the hole in two blocks // 00109 p = (void *)p_best + sizeof(mem_block_t) + size; 00110 p->magic = M_MAGIC; 00111 p->flags = M_FREE; 00112 p->size = p_best->size - size - sizeof(mem_block_t); 00113 p->owner = NULL; 00114 00115 p_best->size = size; 00116 p_best = (void *)p_best + sizeof(mem_block_t); 00117 00118 SET_IF(IF); 00119 // Return the best-fit pointer // 00120 return ((void *)p_best); 00121 } |
|
Initialize the kernel virtual memory area.
Definition at line 22 of file kmalloc.c.
00023 { 00024 mem_block_t *p; 00025 00026 // Create only one hudge block // 00027 p = (mem_block_t *)K_HEAP_START; 00028 p->magic = M_MAGIC; 00029 p->flags = M_FREE; 00030 p->size = K_HEAP_END - K_HEAP_START - sizeof(mem_block_t); 00031 p->owner = NULL; 00032 } |
|
Allocate some memory aligned to a boundary.
Definition at line 308 of file kmalloc.c.
00309 { 00310 mem_block_t *p, *p2; 00311 dword IF = GET_IF(); 00312 00313 // Cannot allocate memory with a size of zero // 00314 if ( !size ) 00315 return(NULL); 00316 00317 // Allocate the pointer // 00318 p = kmalloc(size + alignment + 2*sizeof(mem_block_t)); 00319 if ( p == NULL ) 00320 return(NULL); 00321 00322 // An alignment of zero is intended as a simple kmalloc(size) // 00323 if ( alignment == 0 ) 00324 { 00325 return(p); 00326 } 00327 00328 // Check if the pointer is correcly aligned // 00329 if ( (size_t)(p) % alignment ) 00330 { 00331 // Align the pointer p to the boundary. // 00332 disable(); 00333 00334 // Allocate the new block // 00335 p2 = p + 2; 00336 p2 = (mem_block_t *)ALIGN_UP((size_t)p2, alignment) - 1; 00337 p2->magic = M_MAGIC; 00338 p2->flags = (p-1)->flags; 00339 p2->owner = (p-1)->owner; 00340 p2->size = mem_sizeof(p) - ((size_t)(p2+1) - (size_t)p); 00341 00342 // Free the unused space // 00343 (p-1)->size = (size_t)p2 - (size_t)p; 00344 kfree(p); 00345 00346 SET_IF(IF); 00347 00348 return(p2+1); 00349 } 00350 else 00351 // The pointer p is already aligned to the boudary // 00352 return(p); 00353 } |
|
Return the size of the pointer ptr passed as argument.
Definition at line 287 of file kmalloc.c.
00288 { 00289 // Return the size of the pointer "ptr", or NULL if an error occurs // 00290 mem_block_t *p = ((mem_block_t *)ptr-1); 00291 00292 if ( (p->magic == M_MAGIC) && (p->flags == M_ALLOC) ) 00293 return( p->size ); 00294 else 00295 return(NULL); 00296 } |