AquilaOS documentation
How it works, and its code
Loading...
Searching...
No Matches
vmem.c File Reference

vmem, an allocator of ranges of addresses (see mm/vmem.h). More...

#include <core/system.h>
#include <core/panic.h>
#include <core/string.h>
#include <mm/vmem.h>

Go to the source code of this file.

Functions

static int log2_floor (size_t n)
 Returns log2(n) rounded down; n must not be 0.
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 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 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.
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 void seg_unlink (struct vmem *vm, struct vmem_seg *seg)
 Takes seg off the arena's list of segments.
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.
struct vmem_seg * vmem_find (struct vmem *vm, uintptr_t base)
 Finds the allocated segment that starts at an address.
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.
void vmem_free (struct vmem *vm, struct vmem_seg *seg)
 Frees an allocated segment.

Detailed Description

vmem, an allocator of ranges of addresses (see mm/vmem.h).

Definition in file vmem.c.

Function Documentation

◆ free_list()

struct vmem_seg ** free_list ( struct vmem * vm,
struct vmem_seg * seg )
static

Returns the free list that a free segment belongs on, by its size.

Definition at line 26 of file vmem.c.

References vmem::free, free_list(), log2_floor(), and vmem::quantum.

Referenced by free_list(), seg_merge(), vmem_alloc(), vmem_free(), and vmem_init().

◆ hash_chain()

struct vmem_seg ** hash_chain ( struct vmem * vm,
uintptr_t base )
static

Returns the hash chain of the allocated segments that start at base.

Definition at line 32 of file vmem.c.

References vmem_seg::base, vmem::hash, hash_chain(), vmem::quantum, and VMEM_HASH.

Referenced by hash_chain(), vmem_alloc(), vmem_find(), and vmem_free().

◆ list_insert()

void list_insert ( struct vmem_seg ** list,
struct vmem_seg * seg )
static

Puts a segment at the head of a free list or a hash chain, through its lprev and lnext.

Definition at line 39 of file vmem.c.

References list_insert(), and NULL.

Referenced by list_insert(), seg_merge(), vmem_alloc(), vmem_free(), and vmem_init().

◆ log2_ceil()

int log2_ceil ( size_t n)
static

Returns log2(n) rounded up; n must not be 0.

Definition at line 19 of file vmem.c.

References log2_ceil(), and log2_floor().

Referenced by log2_ceil(), and vmem_alloc().

◆ log2_floor()

int log2_floor ( size_t n)
static

Returns log2(n) rounded down; n must not be 0.

Definition at line 13 of file vmem.c.

References log2_floor().

Referenced by free_list(), log2_ceil(), log2_floor(), and vmem_alloc().

◆ seg_link()

void seg_link ( struct vmem * vm,
struct vmem_seg * prev,
struct vmem_seg * seg )
static

Links seg into the arena's list of segments, in address order, right after prev (NULL: as the first).

Definition at line 66 of file vmem.c.

References vmem_seg::next, vmem_seg::prev, seg_link(), and vmem::segs.

Referenced by seg_link(), vmem_alloc(), and vmem_init().

◆ seg_list_remove()

void seg_list_remove ( struct vmem_seg ** list,
struct vmem_seg * seg )
static

Takes a segment off the free list or hash chain it is on.

Definition at line 51 of file vmem.c.

References NULL, and seg_list_remove().

Referenced by seg_list_remove(), seg_merge(), vmem_alloc(), and vmem_free().

◆ seg_merge()

void seg_merge ( struct vmem * vm,
struct vmem_seg * a,
struct vmem_seg * b )
static

Merges the free segment b into the free segment a, which comes right before it.

Definition at line 204 of file vmem.c.

References free_list(), kfree(), list_insert(), seg_list_remove(), seg_merge(), seg_unlink(), and vmem_seg::size.

Referenced by seg_merge(), and vmem_free().

◆ seg_unlink()

void seg_unlink ( struct vmem * vm,
struct vmem_seg * seg )
static

Takes seg off the arena's list of segments.

Definition at line 81 of file vmem.c.

References seg_unlink(), and vmem::segs.

Referenced by seg_merge(), and seg_unlink().

◆ vmem_alloc()

struct vmem_seg * vmem_alloc ( struct vmem * vm,
size_t size )

Allocates a range from an arena.

Parameters
vmthe arena
sizethe size wanted, in bytes (rounded up to a multiple of the quantum)
Returns
the allocated segment, or NULL if there is no free range that large, or no memory for the record of what's left

Definition at line 134 of file vmem.c.

References vmem_seg::base, vmem::free, vmem_seg::free, free_list(), hash_chain(), vmem::inuse, kmalloc(), list_insert(), log2_ceil(), log2_floor(), M_ZERO, NULL, vmem::quantum, seg_link(), seg_list_remove(), vmem_seg::size, vmem_alloc(), and VMEM_LISTS.

Referenced by kvmem_alloc(), and vmem_alloc().

◆ vmem_find()

struct vmem_seg * vmem_find ( struct vmem * vm,
uintptr_t base )

Finds the allocated segment that starts at an address.

Parameters
vmthe arena
basethe address
Returns
the segment, or NULL if no allocated segment starts there

Definition at line 193 of file vmem.c.

References vmem_seg::base, hash_chain(), NULL, and vmem_find().

Referenced by kfree(), and vmem_find().

◆ vmem_free()

void vmem_free ( struct vmem * vm,
struct vmem_seg * seg )

Frees an allocated segment.

It merges with the free segments next to it, so that the arena doesn't fragment. Freeing a free segment panics.

Parameters
vmthe arena
segthe segment, which vmem_alloc() gave

Definition at line 223 of file vmem.c.

References free_list(), hash_chain(), vmem::inuse, list_insert(), NULL, panic, seg_list_remove(), seg_merge(), and vmem_free().

Referenced by kfree(), kvmem_alloc(), and vmem_free().

◆ vmem_init()

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.

Parameters
vmthe arena
nameits name, for messages
basethe range's start
sizeits size, in bytes (rounded down to a multiple of quantum)
quantumthe unit of allocation: every segment's size is a multiple of it
Returns
0, or -ENOMEM if there was no memory for the first segment

Definition at line 104 of file vmem.c.

References vmem_seg::base, free_list(), kmalloc(), list_insert(), M_ZERO, memset(), vmem::name, NULL, vmem::quantum, seg_link(), vmem::size, vmem_seg::size, and vmem_init().

Referenced by kvmem_setup(), and vmem_init().