memory

package
v0.9.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 31, 2022 License: MIT Imports: 1 Imported by: 0

Documentation

Index

Constants

View Source
const (
	MegaByte = uint64(1024 * 1024)
	GigaByte = 1024 * MegaByte
)

Variables

View Source
var (
	ErrInvalidMemoryClass = errors.New("invalid memory class")
	ErrEarlyMerge         = errors.New("not all children have been freed")
	ErrEmptyPoolOperation = errors.New("operation on empty pool")
)
View Source
var (
	ErrNotEnoughSpace = errors.New("not enough space")
	ErrNotAllocated   = errors.New("no memory allocated at the given offset")
)

Functions

func GetMemoryClassSize

func GetMemoryClassSize(memCls classType) (uint64, error)

GetMemoryClassSize returns size in bytes for a given memory class

func GetMemoryClassType

func GetMemoryClassType(s uint64) classType

GetMemoryClassType returns the minimum memory class type that can hold a device of a given size. The smallest class is 1MB and the largest one is 4GB with 2 bit offset intervals in between, for a total of 7 different classes. This function does not do a validity check

Types

type Allocator

type Allocator interface {
	Allocate(uint64) (MappedRegion, error)
	Release(MappedRegion) error
}

Allocator is an interface for memory allocation

type MappedRegion

type MappedRegion interface {
	Offset() uint64
	Size() uint64
	Type() classType
}

MappedRegion represents a memory block with an offset

type PoolAllocator

type PoolAllocator struct {
	// contains filtered or unexported fields
}

PoolAllocator implements a memory allocation strategy similar to buddy-malloc https://github.com/evanw/buddy-malloc/blob/master/buddy-malloc.c We borrow the idea of spanning a tree of fixed size regions on top of a contiguous memory space.

There are a total of 7 different region sizes that can be allocated, with the smallest being 1MB and the largest 4GB (the default maximum size of a Virtual PMem device).

For efficiency and to reduce fragmentation an entire region is allocated when requested. When there's no available region of requested size, we try to allocate more memory for this particular size by splitting the next available larger region into smaller ones, e.g. if there's no region available for size class 0, we try splitting a region from class 1, then class 2 etc, until we are able to do so or hit the upper limit.

func NewPoolMemoryAllocator

func NewPoolMemoryAllocator() PoolAllocator

func (*PoolAllocator) Allocate

func (pa *PoolAllocator) Allocate(size uint64) (MappedRegion, error)

Allocate checks memory region pool for the given `size` and returns a free region with minimal offset, if none available tries expanding matched memory pool.

Internally it's done via moving a region from free pool into a busy pool

func (*PoolAllocator) Release

func (pa *PoolAllocator) Release(reg MappedRegion) error

Release marks a memory region of class `memCls` and offset `offset` as free and tries to merge smaller regions into a bigger one

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL