207 lines
6.4 KiB
C
207 lines
6.4 KiB
C
#ifndef _LIBMALLOC_BUDDYALLOC_H
|
|
#define _LIBMALLOC_BUDDYALLOC_H
|
|
|
|
#include "memmap.h"
|
|
#include "common.h"
|
|
|
|
/**
|
|
* @brief
|
|
*
|
|
*/
|
|
typedef struct bitmap_heap_descriptor_t
|
|
{
|
|
/**
|
|
* @brief The underlying bitmap representing the availability of chunks of
|
|
* physical memory.
|
|
*
|
|
*/
|
|
unsigned long *bitmap;
|
|
|
|
/**
|
|
* @brief Stores a list of available blocks of memory to speed up allocation.
|
|
*
|
|
*/
|
|
unsigned long *cache;
|
|
|
|
/**
|
|
* @brief The size of the bitmap in bytes.
|
|
*
|
|
*/
|
|
unsigned long bitmap_size;
|
|
|
|
/**
|
|
* @brief The size of the array pointed to by `cache`.
|
|
*
|
|
*/
|
|
unsigned long cache_capacity;
|
|
|
|
/**
|
|
* @brief The size in bytes of the smallest unit of allocation.
|
|
*
|
|
* This value should either be the size of a page on the host system, or
|
|
* possibly some number of pages.
|
|
*
|
|
*/
|
|
unsigned long block_size;
|
|
|
|
/**
|
|
* @brief The height of the binary tree representation of the heap's memory
|
|
* map.
|
|
*
|
|
*/
|
|
unsigned long height;
|
|
|
|
/**
|
|
* @brief The number of available blocks of memory.
|
|
*
|
|
* Due to memory fragmentation, it may not be possible to allocate all
|
|
* available memory at once.
|
|
*
|
|
*/
|
|
unsigned long free_block_count;
|
|
|
|
/**
|
|
* @brief Bitmask used to isolate only those bits which indicate the
|
|
* availability of a block. Useful when several bits are used to represent
|
|
* the state of a single block. See `block_bits`.
|
|
*
|
|
*/
|
|
unsigned long mask;
|
|
|
|
/**
|
|
* @brief The number of bits required to represent the state of each block.
|
|
*
|
|
* If the value is greater than 1, the most significant bit describing each
|
|
* block shall indicate its availability. Less significant bits shall
|
|
* represent other aspects of the block's state. The number of trailing
|
|
* zeroes in `mask` shall be used to calculate this quantity.
|
|
*
|
|
* This qualtity is assumed to be a power of 2, and less than or equal to
|
|
* the number of bits in an unsigned long. Therefore, acceptable values for
|
|
* this quantity are as follows: 1, 2, 4, 8, 16, 32[, 64].
|
|
*
|
|
*/
|
|
unsigned long block_bits;
|
|
|
|
/**
|
|
* @brief The number of blocks described by a single unsigned long contained
|
|
* in `bitmap`. Equal to (8 * sizeof(unsigned long)) / block_bits.
|
|
*
|
|
*/
|
|
unsigned long blocks_in_word;
|
|
|
|
/**
|
|
* @brief Memory will be allocated relative to this location.
|
|
*
|
|
*/
|
|
unsigned long offset;
|
|
|
|
} bitmap_heap_descriptor_t;
|
|
|
|
/**
|
|
* @brief Reads the given bit from the metadata of the memory block at
|
|
* `location`.
|
|
*
|
|
* `location` must have be a location previously returned by `reserve_region`,
|
|
* and not have been subsequently freed. `bit` must be less than the
|
|
* `block_bits` field in `heap`.
|
|
*
|
|
* @returns nonzero if `bit` is set, 0 otherwise. If `bit` is not less than the
|
|
* `block_bits` field in `heap`, returns nonzero.
|
|
*/
|
|
unsigned long read_bit(bitmap_heap_descriptor_t *heap, unsigned long location,
|
|
unsigned long bit);
|
|
|
|
/**
|
|
* @brief Writes to the given bit in the metadata of the memory block at
|
|
* `location`.
|
|
*
|
|
* `location` must have be a location previously returned by `reserve_region`,
|
|
* and not have been subsequently freed. `bit` must be less than the
|
|
* `block_bits` field in `heap`.
|
|
*
|
|
* @returns `value` if bit was written to, nonzero otherwise
|
|
*/
|
|
int write_bit(bitmap_heap_descriptor_t *heap, unsigned long location,
|
|
unsigned long bit, int value);
|
|
|
|
/**
|
|
* @brief Reserves a region of memory within the heap containing at least `size`
|
|
* bytes.
|
|
*
|
|
* If `size` is not a power of two times the block size, it will be rounded up
|
|
* to the smallest possible number which satisfies this condition. After
|
|
*
|
|
* @param heap
|
|
* @param size
|
|
* @return unsigned long
|
|
*/
|
|
unsigned long reserve_region(bitmap_heap_descriptor_t *heap,
|
|
unsigned long size);
|
|
|
|
/**
|
|
* @brief Marks the region of memory indicated by `location` and `size` as
|
|
* available to be allocated.
|
|
*
|
|
* `location` must have been previously returned by `reserve_region`. `size`
|
|
* is expected to be a power of two times the block size.
|
|
*
|
|
* @param heap
|
|
* @param location
|
|
* @param size
|
|
*/
|
|
void free_region(bitmap_heap_descriptor_t *heap, unsigned long location,
|
|
unsigned long size);
|
|
|
|
/**
|
|
* @brief Computes the amount of space required to store the heap's internal
|
|
* bitmaps.
|
|
*
|
|
* @param map A pointer to the structure providing an initial memory layout
|
|
* @param block_size The minimum unit of allocation
|
|
* @return unsigned long
|
|
*/
|
|
unsigned long bitmap_size(const memory_map_t *map, unsigned long block_size, unsigned long block_bits);
|
|
|
|
/**
|
|
* @brief Builds the heap's internal structures according to the memory
|
|
* layout provided in `map`. All locations in `map` are relative to the `offset`
|
|
* field in `heap`.
|
|
*
|
|
* A callback function `mmap` may be provided, which will be used to map the
|
|
* space required by the heap to store its internal bitmaps. If `mmap` is NULL,
|
|
* this function assumes that all space within the heap is already mapped.
|
|
*
|
|
* There are several requirements for the initial state of the `heap` structure:
|
|
*
|
|
* - The `bitmap` field may point to a pre-allocated region of memory which will
|
|
* be used to store the heap's internal bitmap. If this field is NULL, part of
|
|
* the heap will be used to store the bitmap, and `mmap`, if not NULL, will be
|
|
* called to map that region of memory.
|
|
*
|
|
* - The `cache` field may point to an array of unsigned longs of sufficient
|
|
* size, which will be used to speed up memory allocation. If this field is
|
|
* NULL, caching will not be performed.
|
|
*
|
|
* - The `cache_capacity` field must be set to the size of the array pointed to
|
|
* by `cache`.
|
|
*
|
|
* - The `block_size` field must be set to the desired smallest unit of
|
|
* allocation.
|
|
*
|
|
* - The `block_bits` field must be set to the number of bits required to store
|
|
* a block's metadata.
|
|
*
|
|
* - The `offset` field must be set to the first location to allocate memory
|
|
* from. Locations in `map` will be interpreted as relative to `offset`.
|
|
*
|
|
* @param heap A pointer to the structure describing the heap
|
|
* @param map A pointer to the structure providing an initial memory layout
|
|
* @param mmap A callback function used to map memory in the virtual address
|
|
* space
|
|
* @return int 0 upon success, nonzero upon failure.
|
|
*/
|
|
int initialize_heap(bitmap_heap_descriptor_t *heap, memory_map_t *map,
|
|
int (*mmap)(void *location, unsigned long size));
|
|
|
|
#endif |