Initial commit

This commit is contained in:
2023-01-09 01:54:03 -06:00
commit d347b81e72
14 changed files with 856 additions and 0 deletions

1
include/Makefile.am Normal file
View File

@@ -0,0 +1 @@
nobase_include_HEADERS = libmalloc/bitmap_alloc.h libmalloc/memmap.h libmalloc/common.h

View File

@@ -0,0 +1,153 @@
#ifndef _LIBMALLOC_BUDDYALLOC_H
#define _LIBMALLOC_BUDDYALLOC_H
#include "memmap.h"
#include "common.h"
/**
* @brief
*
*/
typedef struct
{
/**
* @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;
} bitmap_heap_descriptor_t;
/**
* @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);
/**
* @brief Builds the heap's internal structures according to the memory
* layout provided in `map`. Assumes that the layout in `map` refers to the
* caller's virtual address space, and utilizes some of the memory marked as
* 'available' to store the heap's internal structures.
*
* 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 `cache` field must be defined, and point to an array of unsigned longs
* of sufficient size.
*
* - The `block_size` field must be set to the desired smallest unit of allocation.
*
* @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
*/
int initialize_virtual_heap(bitmap_heap_descriptor_t *heap, const memory_map_t *map,
int (*mmap)(void *location, unsigned long size));
/**
* @brief Builds the heap's internal structures according to the memory
* layout provided in `map`. Assumes that physical memory space is being alocated,
* and therefore does not make assumptions about the caller's address space or
* attempt to utilize the memory inside the heap. The caller is responsible for
* providing space to store the heap's internal structures.
*
* There are several requirements for the initial state of the `heap` structure:
*
* - The `bitmap` field must be defined, and sufficient memory reserved at that
* location to contain the heap's bitmap.
*
* - The `cache` field must be defined, and point to an array of unsigned longs
* of sufficient size.
*
* - 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.
*
* @param heap A pointer to the structure describing the heap
* @param map A pointer to the structure providing an initial memory layout
* @return int 0 upon success; nonzero upon failure
*/
int initialize_physical_heap(bitmap_heap_descriptor_t *heap, const memory_map_t *map);
#endif

View File

@@ -0,0 +1,13 @@
#ifndef _LIBMALLOC_COMMON_H
#define _LIBMALLOC_COMMON_H
/*
* '0' may possibly refer to a valid memory location for the heap to reserve in
* some circumstances; as a result, NULL is an inappropriate value to use to
* represent the failure to allocate space for the purposes of this library.
* NOMEM shall be returned by any malloc-like function upon failure, rather than
* NULL.
*/
#define NOMEM ~0
#endif

View File

@@ -0,0 +1,27 @@
#ifndef _LIBMALLOC_MEMMAP_H
#define _LIBMALLOC_MEMMAP_H
typedef enum
{
M_AVAILABLE = 1,
M_UNAVAILABLE = 2,
M_DEFECTIVE = 3
} memory_type_t;
typedef struct
{
memory_type_t type;
unsigned long location;
unsigned long size;
} memory_region_t;
typedef struct
{
memory_region_t *array;
unsigned long size;
unsigned long capacity;
} memory_map_t;
int memmap_insert_region(memory_map_t *map, unsigned long location, unsigned long size, memory_type_t type);
#endif

69
include/util.h Normal file
View File

@@ -0,0 +1,69 @@
#ifndef _LIBMALLOC_UTIL_H
#define _LIBMALLOC_UTIL_H
static inline int ilog2(unsigned int x)
{
#if defined __GNUC__
if(x <= 1)
return 0;
return 32 - __builtin_clz(x - 1);
#else
static const int table[32] = {
0, 9, 1, 10, 13, 21, 2, 29,
11, 14, 16, 18, 22, 25, 3, 30,
8, 12, 20, 28, 15, 17, 24, 7,
19, 27, 23, 6, 26, 5, 4, 31};
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
return table[(x * 0x07C4ACDD) >> 27];
#endif
}
static inline int llog2(unsigned long x)
{
#if (defined __GNUC__) && (__SIZEOF_LONG__ == 4)
if(x <= 1)
return 0;
return 32 - __builtin_clzl(x - 1);
#elif (defined __GNUC__) && (__SIZEOF_LONG__ == 8)
if(x <= 1)
return 0;
return 64 - __builtin_clzl(x - 1);
#elif __SIZEOF_LONG__ == 8
static const int table[64] = {
0, 58, 1, 59, 47, 53, 2, 60, 39, 48, 27, 54, 33, 42, 3, 61,
51, 37, 40, 49, 18, 28, 20, 55, 30, 34, 11, 43, 14, 22, 4, 62,
57, 46, 52, 38, 26, 32, 41, 50, 36, 17, 19, 29, 10, 13, 21, 56,
45, 25, 31, 35, 16, 9, 12, 44, 24, 15, 8, 23, 7, 6, 5, 63};
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
x |= x >> 32;
return table[(x * 0x03f6eaf2cd271461) >> 58];
#else
static const int table[32] = {
0, 9, 1, 10, 13, 21, 2, 29,
11, 14, 16, 18, 22, 25, 3, 30,
8, 12, 20, 28, 15, 17, 24, 7,
19, 27, 23, 6, 26, 5, 4, 31};
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
return table[(x * 0x07C4ACDD) >> 27];
#endif
}
#endif