2009-02-08 Vesa Jääskeläinen <chaac@nic.fi>
* kern/mm.c: Add more comments.
This commit is contained in:
parent
e5698dc684
commit
2b40d6bb9f
2 changed files with 79 additions and 22 deletions
|
@ -1,3 +1,7 @@
|
|||
2009-02-08 Vesa Jääskeläinen <chaac@nic.fi>
|
||||
|
||||
* kern/mm.c: Add more comments.
|
||||
|
||||
2009-02-08 Robert Millan <rmh@aybabtu.com>
|
||||
|
||||
Patch from Javier Martín.
|
||||
|
|
57
kern/mm.c
57
kern/mm.c
|
@ -176,16 +176,20 @@ grub_mm_init_region (void *addr, grub_size_t size)
|
|||
}
|
||||
|
||||
/* Allocate the number of units N with the alignment ALIGN from the ring
|
||||
buffer starting from *FIRST. ALIGN must be a power of two. Return a
|
||||
non-NULL if successful, otherwise return NULL. */
|
||||
buffer starting from *FIRST. ALIGN must be a power of two. Both N and
|
||||
ALIGN are in units of GRUB_MM_ALIGN. Return a non-NULL if successful,
|
||||
otherwise return NULL. */
|
||||
static void *
|
||||
grub_real_malloc (grub_mm_header_t *first, grub_size_t n, grub_size_t align)
|
||||
{
|
||||
grub_mm_header_t p, q;
|
||||
|
||||
/* When everything is allocated side effect is that *first will have alloc
|
||||
magic marked, meaning that there is no room in this region. */
|
||||
if ((*first)->magic == GRUB_MM_ALLOC_MAGIC)
|
||||
return 0;
|
||||
|
||||
/* Try to search free slot for allocation in this memory region. */
|
||||
for (q = *first, p = q->next; ; q = p, p = p->next)
|
||||
{
|
||||
grub_off_t extra;
|
||||
|
@ -204,11 +208,37 @@ grub_real_malloc (grub_mm_header_t *first, grub_size_t n, grub_size_t align)
|
|||
{
|
||||
if (extra == 0 && p->size == n)
|
||||
{
|
||||
/* There is no special alignment requirement and memory block
|
||||
is complete match.
|
||||
|
||||
1. Just mark memory block as allocated and remove it from
|
||||
free list.
|
||||
|
||||
Result:
|
||||
+---------------+ previous block's next
|
||||
| alloc, size=n | |
|
||||
+---------------+ v
|
||||
*/
|
||||
q->next = p->next;
|
||||
p->magic = GRUB_MM_ALLOC_MAGIC;
|
||||
}
|
||||
else if (extra == 0 || p->size == n + extra)
|
||||
{
|
||||
/* There might be alignment requirement, when taking it into
|
||||
account memory block fits in.
|
||||
|
||||
1. Allocate new area at end of memory block.
|
||||
2. Reduce size of available blocks from original node.
|
||||
3. Mark new area as allocated and "remove" it from free
|
||||
list.
|
||||
|
||||
Result:
|
||||
+---------------+
|
||||
| free, size-=n | next --+
|
||||
+---------------+ |
|
||||
| alloc, size=n | |
|
||||
+---------------+ v
|
||||
*/
|
||||
p->size -= n;
|
||||
p += p->size;
|
||||
p->size = n;
|
||||
|
@ -216,6 +246,25 @@ grub_real_malloc (grub_mm_header_t *first, grub_size_t n, grub_size_t align)
|
|||
}
|
||||
else
|
||||
{
|
||||
/* There is alignment requirement and there is room in memory
|
||||
block. Split memory block to three pieces.
|
||||
|
||||
1. Create new memory block right after section being
|
||||
allocated. Mark it as free.
|
||||
2. Add new memory block to free chain.
|
||||
3. Mark current memory block having only extra blocks.
|
||||
4. Advance to aligned block and mark that as allocated and
|
||||
"remove" it from free list.
|
||||
|
||||
Result:
|
||||
+------------------------------+
|
||||
| free, size=extra | next --+
|
||||
+------------------------------+ |
|
||||
| alloc, size=n | |
|
||||
+------------------------------+ |
|
||||
| free, size=orig.size-extra-n | <------+, next --+
|
||||
+------------------------------+ v
|
||||
*/
|
||||
grub_mm_header_t r;
|
||||
|
||||
r = p + extra + n;
|
||||
|
@ -230,11 +279,15 @@ grub_real_malloc (grub_mm_header_t *first, grub_size_t n, grub_size_t align)
|
|||
p->magic = GRUB_MM_ALLOC_MAGIC;
|
||||
}
|
||||
|
||||
/* Mark find as a start marker for next allocation to fasten it.
|
||||
This will have side effect of fragmenting memory as small
|
||||
pieces before this will be un-used. */
|
||||
*first = q;
|
||||
|
||||
return p + 1;
|
||||
}
|
||||
|
||||
/* Search was completed without result. */
|
||||
if (p == *first)
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue