#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 }
|
1.2.18