28,7 → 28,6 |
|
#include <mm/buddy.h> |
#include <mm/frame.h> |
#include <mm/heap.h> |
#include <arch/types.h> |
#include <typedefs.h> |
#include <adt/list.h> |
35,10 → 34,18 |
#include <debug.h> |
#include <print.h> |
|
/** Return size needed for the buddy configuration data */ |
size_t buddy_conf_size(int max_order) |
{ |
return sizeof(buddy_system_t) + (max_order + 1) * sizeof(link_t); |
} |
|
|
/** Create buddy system |
* |
* Allocate memory for and initialize new buddy system. |
* |
* @param b Preallocated buddy system control data |
* @param max_order The biggest allocable size will be 2^max_order. |
* @param op Operations for new buddy system. |
* @param data Pointer to be used by implementation. |
45,9 → 52,11 |
* |
* @return New buddy system. |
*/ |
buddy_system_t *buddy_system_create(__u8 max_order, buddy_system_operations_t *op, void *data) |
void buddy_system_create(buddy_system_t *b, |
__u8 max_order, |
buddy_system_operations_t *op, |
void *data) |
{ |
buddy_system_t *b; |
int i; |
|
ASSERT(max_order < BUDDY_SYSTEM_INNER_BLOCK); |
60,20 → 69,10 |
ASSERT(op->mark_busy); |
|
/* |
* Allocate memory for structure describing the whole buddy system. |
* Use memory after our own structure |
*/ |
b = (buddy_system_t *) early_malloc(sizeof(buddy_system_t)); |
b->order = (link_t *) (&b[1]); |
|
if (b) { |
/* |
* Allocate memory for all orders this buddy system will work with. |
*/ |
b->order = (link_t *) early_malloc((max_order + 1) * sizeof(link_t)); |
if (!b->order) { |
early_free(b); |
return NULL; |
} |
|
for (i = 0; i <= max_order; i++) |
list_initialize(&b->order[i]); |
|
82,9 → 81,6 |
b->data = data; |
} |
|
return b; |
} |
|
/** Check if buddy system can allocate block |
* |
* @param b Buddy system pointer |
114,6 → 110,42 |
|
} |
|
/** Allocate PARTICULAR block from buddy system |
* |
* @ return Block of data or NULL if no such block was found |
*/ |
link_t *buddy_system_alloc_block(buddy_system_t *b, link_t *block) |
{ |
link_t *left,*right, *tmp; |
__u8 order; |
|
left = b->op->find_block(b, block, BUDDY_SYSTEM_INNER_BLOCK); |
ASSERT(left); |
list_remove(left); |
while (1) { |
if (! b->op->get_order(b,left)) { |
b->op->mark_busy(b, left); |
return left; |
} |
|
order = b->op->get_order(b, left); |
|
right = b->op->bisect(b, left); |
b->op->set_order(b, left, order-1); |
b->op->set_order(b, right, order-1); |
|
tmp = b->op->find_block(b, block, BUDDY_SYSTEM_INNER_BLOCK); |
|
if (tmp == right) { |
right = left; |
left = tmp; |
} |
b->op->mark_busy(b, left); |
buddy_system_free(b, right); |
b->op->mark_available(b, left); |
} |
} |
|
/** Allocate block from buddy system. |
* |
* @param b Buddy system pointer. |
137,7 → 169,6 |
b->op->mark_busy(b, res); |
return res; |
} |
|
/* |
* If order i is already the maximal order, |
* the request cannot be satisfied. |
167,8 → 198,8 |
b->op->set_order(b, hlp, i); |
|
/* |
* Return the other half to buddy system. |
* PROBLEM!!!! WILL FIND OTHER PART AS BUDDY AND LINK TOGETHER |
* Return the other half to buddy system. Mark the first part |
* full, so that it won't coalsce again. |
*/ |
b->op->mark_busy(b, res); |
buddy_system_free(b, hlp); |