Go to the source code of this file.
Data Structures | |||||
| struct | UMEM_BLOCK | ||||
| A memory block structure. More... | |||||
Defines | |||||
| #define | UM_MAGIC ((uint32_t)"$UM$") | ||||
| Magic number to identify a memory block. | |||||
| #define | UM_FREE 0 | ||||
| Free block. | |||||
| #define | UM_ALLOC 1 | ||||
| Allocated block. | |||||
Typedefs | |||||
| typedef UMEM_BLOCK | umem_block_t | ||||
| A memory block structure. | |||||
Functions | |||||
| void | umalloc_init (size_t heap_start, size_t heap_size) | ||||
Initialize the user virtual memory area.
| |||||
| void * | umalloc (size_t size) | ||||
Allocate a memory block from the user memory area. This is a best-fit like allocator.
| |||||
| void | ufree (void *ptr) | ||||
Frees the memory space pointed by ptr, which must have been returned by a previous call to umalloc(size_t size).
| |||||
Definition in file umalloc.h.
|
|
Allocated block.
|
|
|
Free block.
|
|
|
Magic number to identify a memory block.
|
|
|
A memory block structure.
|
|
|
Frees the memory space pointed by ptr, which must have been returned by a previous call to umalloc(size_t size).
Definition at line 150 of file umalloc.c.
00151 {
00152 task_t *t;
00153 umem_block_t *p, *p2;
00154
00155 if (ptr == NULL) return;
00156
00157 // Point to the header.
00158 p = (void *)ptr - sizeof(umem_block_t);
00159
00160 if (p->magic != UM_MAGIC) return; // Is the process crazy?! :)
00161 if (p->flags != UM_ALLOC) return; // Crazy again?! :)
00162
00163 // Get the current task structure.
00164 t = get_curr_task();
00165
00166 // Free the block.
00167 p->flags = UM_FREE;
00168 p->owner = NULL;
00169
00170 // Try to combine the block wih the next one...
00171 p2 = (void *)p + p->size + sizeof(umem_block_t);
00172
00173 if (p2 < (umem_block_t *)(t->heap_start + t->heap_size))
00174 if (p2->flags == UM_FREE)
00175 {
00176 // Let's merge the two blocks!
00177 p->size += p2->size + sizeof(umem_block_t);
00178 p2->magic = NULL;
00179 }
00180
00181 // Try to combine the block with the previous one...
00182 if (p != (umem_block_t *)(t->heap_start))
00183 {
00184 // Find the previous block.
00185 p2 = (void *)(t->heap_start);
00186 for(;;)
00187 {
00188 if (((void *)p2 + p2->size + sizeof(umem_block_t)) == p)
00189 {
00190 // Block found!
00191 // Check if it's a free block.
00192 if (p2->flags == UM_FREE)
00193 {
00194 // Let's merge the two blocks!
00195 p2->size += (p->size + sizeof(umem_block_t));
00196 p->magic = NULL;
00197 p = p2;
00198 }
00199 break;
00200 }
00201 p2 = (void *)p2 + p2->size + sizeof(umem_block_t);
00202 }
00203 }
00204
00205 // Release the physical space occupied by the block.
00206 deallocate( p );
00207 }
|
|
|
Allocate a memory block from the user memory area. This is a best-fit like allocator.
Definition at line 48 of file umalloc.c.
00049 {
00050 task_t *t;
00051 umem_block_t *p, *p_best=NULL;
00052
00053 if ( !size ) return( NULL ); // Is the process crazy?! :-)
00054
00055 // Get the current task structure.
00056 t = get_curr_task();
00057
00058 // Round the size up to sizeof(umem_block_t); this is the unit
00059 // of allocation.
00060 size = ( size & -(sizeof(umem_block_t)) ) + sizeof(umem_block_t);
00061
00062 // Explore the heap for the best-fit hole.
00063 p=(umem_block_t *)(t->heap_start);
00064 if( !p ) return( NULL );
00065 while(p < (umem_block_t *)(t->heap_start + t->heap_size))
00066 {
00067 // Find a free block.
00068 if (p->flags == UM_FREE)
00069 {
00070 // This block is free... let's proceed!
00071 if (p->size == size)
00072 {
00073 // Best fit block found! You're lucky!
00074 p_best = p;
00075 break;
00076 }
00077 if (p->size > size)
00078 {
00079 // The hole is bigger than size...
00080 // ...check if it's the best-fit hole!
00081 if (p_best==NULL)
00082 p_best = p;
00083 else
00084 if (p_best->size > p->size)
00085 p_best = p;
00086 }
00087 }
00088 // Examine the next memory block.
00089 p = (void *)p+p->size+sizeof(umem_block_t);
00090 }
00091
00092 // Have you found a free block?!
00093 if (p_best == NULL)
00094 {
00095 // No free memory :(
00096 return( NULL );
00097 }
00098
00099 // Found, now allocate it!
00100 p_best->magic = UM_MAGIC;
00101 p_best->flags = UM_ALLOC;
00102 p_best->owner = get_pid();
00103
00104 if (p_best->size == size)
00105 {
00106 p_best = (void *)p_best + sizeof(umem_block_t);
00107 // The block cover the size perfectly.
00108 return( (void *)p_best );
00109 }
00110
00111 // Otherwise split the hole in two blocks.
00112 p = (void *)p_best + sizeof(umem_block_t) + size;
00113 p->magic = UM_MAGIC;
00114 p->flags = UM_FREE;
00115 p->size = p_best->size - size - sizeof(umem_block_t);
00116 p->owner = NULL;
00117
00118 p_best->size = size;
00119 p_best = (void *)p_best + sizeof(umem_block_t);
00120
00121 // Return the best-fit pointer.
00122 return ( (void *)p_best );
00123 }
|
|
||||||||||||
|
Initialize the user virtual memory area.
Definition at line 20 of file umalloc.c.
00021 {
00022 task_t *t;
00023 umem_block_t *p;
00024
00025 t = get_curr_task();
00026 if( t==NULL )
00027 return;
00028
00029 // Setup the heap in the task structure.
00030 t->heap_start = heap_start;
00031 t->heap_size = heap_size;
00032
00033 // Create only one hudge block.
00034 p = (umem_block_t *)heap_start;
00035 p->magic = UM_MAGIC;
00036 p->flags = UM_FREE;
00037 p->size = heap_size - sizeof(umem_block_t);
00038 p->owner = NULL;
00039 }
|
1.2.18