13 #define BUDDY_BLOCK_ORDER 6
47 unsigned int counter = 0;
49 printf(
"BLBT %p:\n", (
void*)blbt);
50 printf(
" Count: %d\n", blbt->
count);
51 printf(
" Order: %d\n", blbt->
order);
53 printf(
" Valid: YES\n");
55 printf(
" Valid: NO\n");
57 printf(
" Pointer Use Size\n");
58 LIST_FOREACH(blt, &blbt->ptr, next_freelist) {
61 printf(
" %11p%8s%16d\n", (
void*)blt,
"FREE", blt->
size);
63 printf(
" %11p%8s%16d\n", (
void*)blt,
"USED", blt->
size);
67 assert(counter == blbt->
count &&
"Count is incorrect!");
87 unsigned long pointer_as_long = (
unsigned long)blt;
91 while (size > (
unsigned int)(1 << blbt->
order)) {
96 pointer_as_long ^= size;
101 if (possible_buddy->
use ==
FREE &&
108 LIST_REMOVE(blt, next_freelist);
111 assert(blbt->
count &&
"bucket containing buddy has zero elements");
113 LIST_REMOVE(possible_buddy, next_freelist);
117 buddy_list_t *smallest_address = (blt < possible_buddy) ? blt : possible_buddy;
120 LIST_INSERT_HEAD(&blbt->ptr, smallest_address, next_freelist);
121 memset(smallest_address+1, 0, smallest_address->
size);
122 blt = smallest_address;
147 while (size > (
unsigned int)(1 << blbt->
order)) {
155 LIST_FOREACH(iter, &blbt->ptr, next_freelist) {
161 assert(0 &&
"buddy with FREE status not in freelist");
164 unsigned int initial_count = blbt->
count;
165 (void) initial_count;
168 if (blbt->
count == 0) {
172 LIST_INSERT_HEAD(&blbt->ptr, blt, next_freelist);
173 memset(blt+1, 0, blt->
size);
174 assert(blbt->
count == initial_count + 1);
179 assert(initial_count > blbt->
count);
187 LIST_INSERT_HEAD(&blbt->ptr, blt, next_freelist);
188 memset(blt+1, 0, blt->
size);
189 assert(blbt->
count == initial_count + 1);
199 assert(bucket->
count &&
"Bucket contains no entries!");
203 assert(blt &&
"LIST_FIRST returned NULL");
205 LIST_REMOVE(blt, next_freelist);
215 void *address = ((
char *)blt) + (1 << bucket->
order);
222 assert(blt != new_blt);
224 LIST_INSERT_HEAD(&bucket->ptr, new_blt, next_freelist);
225 LIST_INSERT_HEAD(&bucket->ptr, blt, next_freelist);
244 while (size > (
unsigned int)(1 << blbt->
order)) {
252 if (blbt->
count == 0) {
253 unsigned split_count = 0;
256 while (blbt->
count == 0) {
265 while (split_count--) {
270 if (LIST_EMPTY(&blbt->ptr)) {
275 assert(blt &&
"LIST_FIRST returned NULL");
276 LIST_REMOVE(blt, next_freelist);
304 if (bsystem == NULL) {
308 for (i = 0; i < list_count; i++) {
309 bsystem[i].
count = 0;
312 LIST_INIT(&(bsystem[i].ptr));
317 size = 1 << power_of_two;
329 bsystem[list_count - 1].
count = 1;
330 LIST_INSERT_HEAD(&bsystem[list_count - 1].ptr, primordial, next_freelist);
struct buddy_list buddy_list_t
void tw_error(const char *file, int line, const char *fmt,...) NORETURN
int dump_buddy_table(buddy_list_bucket_t *buddy_master)
void * buddy_alloc(unsigned size)
static void * buddy_base_address
Buddy-system memory allocator.
buddy_list_bucket_t * g_tw_buddy_master
void buddy_free(void *ptr)
int buddy_try_merge(buddy_list_t *blt)
#define BUDDY_BLOCK_ORDER
Minimum block order.
unsigned int next_power2(unsigned int v)
void * tw_calloc(const char *file, int line, const char *for_who, size_t e_sz, size_t n)
static void buddy_split(buddy_list_bucket_t *bucket)
buddy_list_bucket_t * create_buddy_table(unsigned int power_of_two)
void tw_printf(const char *file, int line, const char *fmt,...)