/* mm.c - functions for memory manager */
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2002 Free Software Foundation, Inc.
+ * Copyright (C) 2002,2005 Free Software Foundation, Inc.
*
* GRUB is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+/*
+ The design of this memory manager.
+
+ This is a simple implementation of malloc with a few extensions. These are
+ the extensions:
+
+ - memalign is implemented efficiently.
+
+ - multiple regions may be used as free space. They may not be
+ contiguous.
+
+ Regions are managed by a singly linked list, and the meta information is
+ stored in the beginning of each region. Space after the meta information
+ is used to allocate memory.
+
+ The memory space is used as cells instead of bytes for simplicity. This
+ is important for some CPUs which may not access multiple bytes at a time
+ when the first byte is not aligned at a certain boundary (typically,
+ 4-byte or 8-byte). The size of each cell is equal to the size of struct
+ grub_mm_header, so the header of each allocated/free block fits into one
+ cell precisely. One cell is 16 bytes on 32-bit platforms and 32 bytes
+ on 64-bit platforms.
+
+ There are two types of blocks: allocated blocks and free blocks.
+
+ In allocated blocks, the header of each block has only its size. Note that
+ this size is based on cells but not on bytes. The header is located right
+ before the returned pointer, that is, the header resides at the previous
+ cell.
+
+ Free blocks constitutes a ring, using a singly linked list. The first free
+ block is pointed to by the meta information of a region. The allocator
+ attempts to pick up the second block instead of the first one. This is
+ a typical optimization against defragmentation, and makes the
+ implementation a bit easier.
+
+ For safety, both allocated blocks and free ones are marked by magic
+ numbers. Whenever anything unexpected is detected, GRUB aborts the
+ operation.
+ */
+
#include <config.h>
#include <grub/mm.h>
#include <grub/misc.h>
#if GRUB_CPU_SIZEOF_VOID_P == 4
# define GRUB_MM_ALIGN_LOG2 4
#elif GRUB_CPU_SIZEOF_VOID_P == 8
-# define GRUB_MM_ALIGN_LOG2 8
+# define GRUB_MM_ALIGN_LOG2 5
#endif
#define GRUB_MM_ALIGN (1 << GRUB_MM_ALIGN_LOG2)