pool

package
v0.1.11 Latest Latest
Warning

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

Go to latest
Published: Sep 12, 2026 License: Apache-2.0 Imports: 2 Imported by: 0

Documentation

Overview

Package pool holds the free-frame list shared by packetio backends.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Checked

func Checked() bool

Checked reports whether this build detects a frame returned twice.

Types

type Frames

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

Frames is a LIFO free list of frame offsets for one direction of one queue.

It is not synchronized, by design. Each pool belongs to exactly one goroutine, and pools that a receive goroutine and a transmit goroutine touch concurrently must cover disjoint ranges of the region. That is what lets the packet path run without a lock. go-afxdp learned this the hard way: sharing one free list across both directions handed the same frame to a fill and a transmit at once, which corrupts packets on the wire and is invisible in local counters.

A LIFO rather than a FIFO because the most recently freed frame is the one most likely to still be in cache.

func New

func New(base, count, frameSize int) *Frames

New builds a pool holding count frames of frameSize bytes each, starting at frame index base. The frames cover [base*frameSize, (base+count)*frameSize) of the region.

func (*Frames) Base

func (p *Frames) Base(addr uint64) uint64

Base rounds a descriptor address down to the start of its frame. Frames are laid out at fixed multiples of frameSize from the start of the region, so this recovers the frame a descriptor belongs to whatever headroom it used.

The frame size is a power of two, so this is a mask. It is called once per packet on the way back to the free list, where a divide would be pure waste.

func (*Frames) FrameSize

func (p *Frames) FrameSize() int

FrameSize is the size of one frame.

func (*Frames) Len

func (p *Frames) Len() int

Len is how many frames are free.

func (*Frames) Owns

func (p *Frames) Owns(addr uint64) bool

Owns reports whether addr falls inside a frame of this pool. It is for assertions and tests, not for the packet path.

func (*Frames) Pop

func (p *Frames) Pop(n int, dst []uint64) []uint64

Pop removes up to n frames and appends their offsets to dst, returning the grown slice. It appends fewer than n when fewer are free, and allocates nothing when dst has the capacity.

func (*Frames) Push

func (p *Frames) Push(addr uint64)

Push returns one frame. addr must be the start of a frame of this pool: callers hold a descriptor whose Addr may point past the frame start, so they round down with Base first.

A push is refused and counted, rather than appended, when the frame is not this pool's, when it is not the start of a frame, when it is already on the free list, or when the pool is already full. Every one of them is a caller returning a frame twice or to the wrong queue, and every one would otherwise hand a frame to two owners -- the corruption that is invisible in every other counter. A shift and a mask; not worth leaving out.

func (*Frames) Rejected

func (p *Frames) Rejected() uint64

Rejected is how many pushes were refused: foreign, unaligned, already free, or surplus. Anything but zero is a bug in the code above the pool.

Jump to

Keyboard shortcuts

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