Add buddy_owned and buddy_allocated
This commit is contained in:
@@ -162,8 +162,8 @@
|
|||||||
*/
|
*/
|
||||||
#define MAX_BLOCK_LOG2 BUDDY_ALLOC_MAX_BLOCK_LOG2
|
#define MAX_BLOCK_LOG2 BUDDY_ALLOC_MAX_BLOCK_LOG2
|
||||||
#define MIN_BLOCK_LOG2 BUDDY_ALLOC_MIN_BLOCK_LOG2
|
#define MIN_BLOCK_LOG2 BUDDY_ALLOC_MIN_BLOCK_LOG2
|
||||||
#define MAX_BLOCK_SIZE BUDDY_ALLOC_MAX_BLOCK_LOG2
|
#define MAX_BLOCK_SIZE BUDDY_ALLOC_MAX_BLOCK_SIZE
|
||||||
#define MIN_BLOCK_SIZE BUDDY_ALLOC_MIN_BLOCK_LOG2
|
#define MIN_BLOCK_SIZE BUDDY_ALLOC_MIN_BLOCK_SIZE
|
||||||
#define MAX_BLOCK_ALIGN_MASK (MAX_BLOCK_SIZE - 1)
|
#define MAX_BLOCK_ALIGN_MASK (MAX_BLOCK_SIZE - 1)
|
||||||
|
|
||||||
struct page { struct page *next; };
|
struct page { struct page *next; };
|
||||||
@@ -182,6 +182,7 @@ static struct buddy_alloc startup_empty()
|
|||||||
{
|
{
|
||||||
struct buddy_alloc alloc;
|
struct buddy_alloc alloc;
|
||||||
alloc.base = NULL;
|
alloc.base = NULL;
|
||||||
|
alloc.size = 0;
|
||||||
alloc.info = NULL;
|
alloc.info = NULL;
|
||||||
alloc.num_info = 0;
|
alloc.num_info = 0;
|
||||||
for (int i = 0; i < BUDDY_ALLOC_NUM_LISTS; i++)
|
for (int i = 0; i < BUDDY_ALLOC_NUM_LISTS; i++)
|
||||||
@@ -249,6 +250,7 @@ struct buddy_alloc buddy_startup(char *base, size_t size,
|
|||||||
|
|
||||||
struct buddy_alloc alloc;
|
struct buddy_alloc alloc;
|
||||||
alloc.base = base,
|
alloc.base = base,
|
||||||
|
alloc.size = size;
|
||||||
alloc.info = info;
|
alloc.info = info;
|
||||||
alloc.num_info = num_info;
|
alloc.num_info = num_info;
|
||||||
|
|
||||||
@@ -426,11 +428,14 @@ static void set_allocated(struct buddy_alloc *alloc,
|
|||||||
size_t i = page_index(alloc, ptr);
|
size_t i = page_index(alloc, ptr);
|
||||||
size_t j = block_info_index(ptr, len);
|
size_t j = block_info_index(ptr, len);
|
||||||
|
|
||||||
int bits_per_word_log2 = 5;
|
size_t bits_per_word_log2 = 5;
|
||||||
int bits_per_word = 1 << bits_per_word_log2;
|
size_t bits_per_word = 1 << bits_per_word_log2;
|
||||||
|
|
||||||
int u = j >> bits_per_word_log2;
|
size_t u = j >> bits_per_word_log2;
|
||||||
int v = j & (bits_per_word - 1);
|
size_t v = j & (bits_per_word - 1);
|
||||||
|
|
||||||
|
assert(i < (size_t) alloc->num_info);
|
||||||
|
assert(u < BUDDY_ALLOC_WORDS_PER_PAGE);
|
||||||
|
|
||||||
uint32_t mask = 1U << v;
|
uint32_t mask = 1U << v;
|
||||||
if (value)
|
if (value)
|
||||||
@@ -465,7 +470,8 @@ static size_t normalize_len(size_t len)
|
|||||||
|
|
||||||
static int list_index_for_size(size_t len)
|
static int list_index_for_size(size_t len)
|
||||||
{
|
{
|
||||||
return first_set(len) - MIN_BLOCK_LOG2;
|
int i = first_set(len);
|
||||||
|
return i - MIN_BLOCK_LOG2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the sibling block of the one at position "ptr". If the block
|
// Get the sibling block of the one at position "ptr". If the block
|
||||||
@@ -555,9 +561,11 @@ void *buddy_malloc(struct buddy_alloc *alloc, size_t len)
|
|||||||
if (alloc->base == NULL)
|
if (alloc->base == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
len = normalize_len(len);
|
len = normalize_len(len);
|
||||||
|
assert(len >= MIN_BLOCK_SIZE);
|
||||||
|
|
||||||
// Index of the list of blocks with size "len"
|
// Index of the list of blocks with size "len"
|
||||||
int i = list_index_for_size(len);
|
int i = list_index_for_size(len);
|
||||||
|
assert(i >= 0 && i < BUDDY_ALLOC_NUM_LISTS);
|
||||||
|
|
||||||
// Get the index of the first non-empty list
|
// Get the index of the first non-empty list
|
||||||
int j = i;
|
int j = i;
|
||||||
@@ -620,3 +628,14 @@ void buddy_free(struct buddy_alloc *alloc,
|
|||||||
len <<= 1;
|
len <<= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool buddy_owned(struct buddy_alloc *alloc, void *ptr)
|
||||||
|
{
|
||||||
|
return (uintptr_t) alloc->base <= (uintptr_t) ptr
|
||||||
|
&& (uintptr_t) alloc->base + alloc->size > (uintptr_t) ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool buddy_allocated(struct buddy_alloc *alloc, void *ptr, size_t len)
|
||||||
|
{
|
||||||
|
return buddy_owned(alloc, ptr) && is_allocated(alloc, ptr, len);
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
/* === INTRODUCTION ===
|
/* === INTRODUCTION ===
|
||||||
* This is the implementation of a general purpose allocator that uses
|
* This is the implementation of a general purpose allocator that uses
|
||||||
@@ -46,6 +47,7 @@ _Static_assert(BUDDY_ALLOC_MIN_BLOCK_LOG2 > 2);
|
|||||||
#define BUDDY_ALLOC_NUM_LISTS (BUDDY_ALLOC_MAX_BLOCK_LOG2 - BUDDY_ALLOC_MIN_BLOCK_LOG2 + 1)
|
#define BUDDY_ALLOC_NUM_LISTS (BUDDY_ALLOC_MAX_BLOCK_LOG2 - BUDDY_ALLOC_MIN_BLOCK_LOG2 + 1)
|
||||||
#define BUDDY_ALLOC_MAX_BLOCK_SIZE (1U << BUDDY_ALLOC_MAX_BLOCK_LOG2)
|
#define BUDDY_ALLOC_MAX_BLOCK_SIZE (1U << BUDDY_ALLOC_MAX_BLOCK_LOG2)
|
||||||
#define BUDDY_ALLOC_MIN_BLOCK_SIZE (1U << BUDDY_ALLOC_MIN_BLOCK_LOG2)
|
#define BUDDY_ALLOC_MIN_BLOCK_SIZE (1U << BUDDY_ALLOC_MIN_BLOCK_LOG2)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* To keep track of the allocation state of a page,
|
* To keep track of the allocation state of a page,
|
||||||
* we need one bit for each possible block that can
|
* we need one bit for each possible block that can
|
||||||
@@ -66,7 +68,8 @@ struct page_info {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct buddy_alloc {
|
struct buddy_alloc {
|
||||||
void *base;
|
void *base;
|
||||||
|
size_t size;
|
||||||
void *lists[BUDDY_ALLOC_NUM_LISTS];
|
void *lists[BUDDY_ALLOC_NUM_LISTS];
|
||||||
struct page_info *info;
|
struct page_info *info;
|
||||||
int num_info;
|
int num_info;
|
||||||
@@ -106,3 +109,7 @@ void *buddy_malloc(struct buddy_alloc *alloc, size_t len);
|
|||||||
* allocating.
|
* allocating.
|
||||||
*/
|
*/
|
||||||
void buddy_free(struct buddy_alloc *alloc, size_t len, void *ptr);
|
void buddy_free(struct buddy_alloc *alloc, size_t len, void *ptr);
|
||||||
|
|
||||||
|
bool buddy_owned(struct buddy_alloc *alloc, void *ptr);
|
||||||
|
|
||||||
|
bool buddy_allocated(struct buddy_alloc *alloc, void *ptr, size_t len);
|
||||||
Reference in New Issue
Block a user