39 static inline int left_child(
int index)
42 return ((index << 1) + 1);
45 static inline int right_child(
int index)
48 return ((index << 1) + 2);
51 static inline int parent(
int index)
54 return (((index + 1) >> 1) - 1);
57 static inline bool is_power_of_2(
int index)
59 return !(index & (index - 1));
62 static inline size_t next_power_of_2(
size_t size)
80 struct buddy *
self = NULL;
84 if (num_of_fragments < 1 || !is_power_of_2(num_of_fragments)) {
91 self = (
struct buddy *)rsalloc(
sizeof(
struct buddy) + 2 * num_of_fragments *
sizeof(size_t));
92 bzero(
self,
sizeof(
struct buddy) + 2 * num_of_fragments *
sizeof(
size_t));
94 self->size = num_of_fragments;
95 node_size = num_of_fragments * 2;
98 int iter_end = num_of_fragments * 2 - 1;
99 for (i = 0; i < iter_end; i++) {
100 if (is_power_of_2(i + 1)) {
103 self->longest[i] = node_size;
111 void buddy_destroy(
struct buddy *
self)
120 if (
self == NULL || self->size <= size) {
124 size = next_power_of_2(size);
127 if (self->longest[index] < size) {
132 size_t node_size = 0;
133 for (node_size = self->size; node_size != size; node_size >>= 1) {
136 if (self->longest[left_child(index)] >= size) {
137 index = left_child(index);
139 index = right_child(index);
144 self->longest[index] = 0;
145 int offset = (index + 1) * node_size - self->size;
148 index = parent(index);
149 self->longest[index] =
max(self->longest[left_child(index)], self->longest[right_child(index)]);
155 void buddy_free(
struct buddy *
self,
size_t offset)
157 if (
self == NULL || offset >= self->size) {
166 index = offset +
self->size - 1;
168 for (;
self->longest[index] != 0; index = parent(index)) {
176 self->longest[index] = node_size;
179 index = parent(index);
182 size_t left_longest =
self->longest[left_child(index)];
183 size_t right_longest =
self->longest[right_child(index)];
185 if (left_longest + right_longest == node_size) {
186 self->longest[index] = node_size;
188 self->longest[index] =
max(left_longest, right_longest);
193 void *allocate_lp_memory(
struct lp_struct *lp,
size_t size)
195 long long offset, displacement;
204 fragments = 1 + ((size - 1) / BUDDY_GRANULARITY);
208 displacement = offset * BUDDY_GRANULARITY;
213 return (
void *)((
char *)lp->
mm->segment->base + displacement);
216 void free_lp_memory(
struct lp_struct *lp,
void *ptr)
220 displacement = (int)((
char *)ptr - (
char *)lp->
mm->segment->base);
222 buddy_free(lp->
mm->buddy, displacement);
#define spinlock_init(s)
Spinlock initialization.
Core ROOT-Sim functionalities.
struct memory_map * mm
Memory map of the LP.
Memory Manager main header.
void spin_lock(spinlock_t *s)
struct buddy * buddy_new(struct lp_struct *lp, size_t num_of_fragments)
#define max(a, b)
Macro to find the maximum among two values.
int buddy_alloc(struct buddy *self, size_t size)
#define unlikely(exp)
Optimize the branch as likely not taken.
void spin_unlock(spinlock_t *s)