mach

package
v0.6.18 Latest Latest
Warning

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

Go to latest
Published: Aug 22, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package mach provides a small, hand-written discipline layer over the raw Mach bindings in the kernel package: thread ports and real-time thread promotion.

The raw calls (thread_policy_set, mach_port_deallocate, ...) are generated into the kernel package from Apple's Kernel framework documentation. What generation cannot supply lives here: acquiring the right thread port without leaking a port right, converting durations to Mach absolute time units, and the pin-then-promote calling discipline.

Promotion applies to an OS thread, not a goroutine. Callers must hold the thread with runtime.LockOSThread before promoting, and the promotion lasts until the thread is demoted or exits:

runtime.LockOSThread()
defer runtime.UnlockOSThread()
t := mach.ThreadSelf()
err := t.SetTimeConstraint(mach.TimeConstraint{
	Period:      time.Millisecond * 10,
	Computation: time.Millisecond * 2,
	Constraint:  time.Millisecond * 4,
	Preemptible: true,
})

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BootstrapRegister

func BootstrapRegister(name string, p Port) error

BootstrapRegister registers a send right for p under name in this session's bootstrap namespace, making it visible to BootstrapLookUp in other processes. p must carry a send right (see MakeSendRight).

bootstrap_register is deprecated in favor of launchd job submission, but remains the only route for an unprivileged process to publish a port at runtime, which is exactly the rendezvous case this package serves.

func Send

func Send(dest Port, destDisp Disposition, id int32, rights []PortRight, body []byte, timeout time.Duration) error

Send sends a message to dest. destDisp says what right the send consumes to address dest (CopySend keeps the caller's send right, MoveSend consumes it, MakeSend requires dest be a receive right). Attached port rights cross by their own dispositions. timeout zero blocks.

The kernel both reads the buffer and requires it not move; the buffer is built pointer-free and pinned for the call.

Types

type Disposition

type Disposition uint32

Disposition says how a port right crosses in a message (mach_msg_type_name_t). MoveSend consumes the sender's right; CopySend does not. Getting this backwards leaks a right or produces a dead name — see the leak tests.

const (
	MoveReceive  Disposition = 16
	MoveSend     Disposition = 17
	MoveSendOnce Disposition = 18
	CopySend     Disposition = 19
	MakeSend     Disposition = 20
	MakeSendOnce Disposition = 21
)
type Header struct {
	Bits        uint32
	Size        uint32
	RemotePort  Port
	LocalPort   Port
	VoucherPort Port
	ID          int32
}

Header is mach_msg_header_t with its field names restored.

The generated kernel.Mach_msg_header_t is an opaque [6]uint32: Apple's documentation describes the typedef and the field names live on the anonymous struct, so the generator cannot recover them. The layout is ABI pinned to xnu, not to the SDK documentation, so owning it here as a hand-written struct is correct, with the size assertions below tying it to the generated type so a change on either side breaks the build.

type Message

type Message struct {
	Header Header
	Ports  []Port
	Body   []byte
}

Message is a received Mach message: the header, any port rights carried in descriptors, and the inline body bytes.

Received rights are owned by the caller and must be balanced (Deallocate for send rights) like any other acquired right.

Mach message sizes are word-aligned, so Body carries up to three bytes of zero padding beyond what was sent; protocols that need exact lengths carry them in the body or the ID.

func Receive

func Receive(p Port, timeout time.Duration) (*Message, error)

Receive blocks on p's receive right until a message arrives or timeout elapses (zero blocks indefinitely). Port rights carried in descriptors are extracted into Message.Ports and owned by the caller.

type Port

type Port uint32

Port is a Mach port name in this task's port namespace.

Port rights are reference-counted in the kernel and leak silently: a leaked receive right keeps its object alive forever, and a dropped send right becomes a dead name whose next use fails far from the bug. A Port is a name, not an object — Go's GC cannot manage right lifetime, so every acquired right is balanced explicitly with Deallocate or DestroyReceive, typically via defer.

const PortNull Port = 0

PortNull is the null port name.

func BootstrapLookUp

func BootstrapLookUp(name string) (Port, error)

BootstrapLookUp returns a send right to the port registered under name. The caller owns the returned right and balances it with Deallocate.

func NewPort

func NewPort() (Port, error)

NewPort allocates a receive right. Balance with DestroyReceive.

func TaskSelf

func TaskSelf() Port

TaskSelf returns this task's port.

func (Port) Deallocate

func (p Port) Deallocate() error

Deallocate releases one send, send-once, or dead-name reference.

func (Port) DestroyReceive

func (p Port) DestroyReceive() error

DestroyReceive releases p's receive right.

func (Port) MakeSendRight

func (p Port) MakeSendRight() error

MakeSendRight adds a send right for p's receive right under the same name. Balance with Deallocate.

func (Port) ModRefs

func (p Port) ModRefs(right Right, delta int) error

ModRefs adjusts the user-reference count for one right kind.

func (Port) Refs

func (p Port) Refs(right Right) (int, error)

Refs reports the user-reference count this task holds for one right kind on p. A name with no such right reports zero (the kernel returns KERN_INVALID_NAME, which is the answer, not an error, for leak checks).

type PortRight

type PortRight struct {
	Port        Port
	Disposition Disposition
}

PortRight names a port right to carry in a message.

type Right uint32

Right identifies a port right kind for ModRefs and Refs.

const (
	RightSend     Right = 0
	RightReceive  Right = 1
	RightSendOnce Right = 2
)

Port right kinds (mach_port_right_t).

type Thread

type Thread uint32

Thread is a Mach thread port name.

func ThreadSelf

func ThreadSelf() (Thread, error)

ThreadSelf returns the Mach thread port of the calling OS thread.

It resolves the port via pthread_mach_thread_np(pthread_self()) rather than mach_thread_self: the pthread route borrows the port cached in the pthread structure, so no port right is allocated and nothing needs to be deallocated. The result is only meaningful for the current OS thread; pin it with runtime.LockOSThread before using the port.

func (Thread) SetStandard

func (t Thread) SetStandard() error

SetStandard demotes the thread back to the standard scheduling class.

func (Thread) SetTimeConstraint

func (t Thread) SetTimeConstraint(tc TimeConstraint) error

SetTimeConstraint promotes the thread to the real-time scheduling class. The calling goroutine must be locked to the thread t was obtained from.

type TimeConstraint

type TimeConstraint struct {
	Period      time.Duration
	Computation time.Duration
	Constraint  time.Duration
	Preemptible bool
}

TimeConstraint describes a real-time scheduling contract, as passed to THREAD_TIME_CONSTRAINT_POLICY. Period is the interval between deadlines (for audio, the buffer duration), Computation the CPU time needed per period, and Constraint the window within which that computation must complete (Computation <= Constraint <= Period).

Jump to

Keyboard shortcuts

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