15 return (
int) (
sizeof(
size_t) * 8 - 1) - __builtin_clzl(n);
22 return ((
size_t) 1 << l) == n ? l : l + 1;
54 seg->lprev->lnext =
seg->lnext;
59 seg->lnext->lprev =
seg->lprev;
84 seg->prev->next =
seg->next;
89 seg->next->prev =
seg->prev;
106 memset(vm, 0,
sizeof(*vm));
150 if (s->size >= n * vm->
quantum)
226 panic(
"vmem_free: a free segment");
237 if (
seg->next &&
seg->next->free)
240 if (
seg->prev &&
seg->prev->free)
#define MALLOC_DEFINE(type, _name, _desc)
void * kmalloc(size_t size, struct malloc_type *type, int flags)
Allocates memory for one of the kernel's structures.
void kfree(void *)
Frees an object that kmalloc() gave.
void * memset(void *dst, int c, size_t n)
Sets n bytes to c.
A list: its first and last nodes, and how many there are.
A received segment, with its header in host byte order.
A segment of an arena: a range that is either free or allocated.
An arena: a range, and its segments.
struct vmem_seg * free[VMEM_LISTS]
struct vmem_seg * hash[VMEM_HASH]
static int log2_ceil(size_t n)
Returns log2(n) rounded up; n must not be 0.
static struct vmem_seg ** free_list(struct vmem *vm, struct vmem_seg *seg)
Returns the free list that a free segment belongs on, by its size.
static int log2_floor(size_t n)
Returns log2(n) rounded down; n must not be 0.
static void seg_link(struct vmem *vm, struct vmem_seg *prev, struct vmem_seg *seg)
Links seg into the arena's list of segments, in address order, right after prev (NULL: as the first).
static struct vmem_seg ** hash_chain(struct vmem *vm, uintptr_t base)
Returns the hash chain of the allocated segments that start at base.
static void seg_merge(struct vmem *vm, struct vmem_seg *a, struct vmem_seg *b)
Merges the free segment b into the free segment a, which comes right before it.
static void seg_unlink(struct vmem *vm, struct vmem_seg *seg)
Takes seg off the arena's list of segments.
static void list_insert(struct vmem_seg **list, struct vmem_seg *seg)
Puts a segment at the head of a free list or a hash chain, through its lprev and lnext.
static void seg_list_remove(struct vmem_seg **list, struct vmem_seg *seg)
Takes a segment off the free list or hash chain it is on.
int vmem_init(struct vmem *vm, const char *name, uintptr_t base, size_t size, size_t quantum)
Sets up an arena: the range [base, base + size), all free.
struct vmem_seg * vmem_alloc(struct vmem *vm, size_t size)
Allocates a range from an arena.
void vmem_free(struct vmem *vm, struct vmem_seg *seg)
Frees an allocated segment.
struct vmem_seg * vmem_find(struct vmem *vm, uintptr_t base)
Finds the allocated segment that starts at an address.