Documentation ¶
Overview ¶
Package futex provides an implementation of the futex interface as found in the Linux kernel. It allows one to easily transform Wait() calls into waits on a channel, which is useful in a Go-based kernel, for example.
Index ¶
- type Checker
- type Manager
- func (m *Manager) Requeue(addr uintptr, naddr uintptr, nwake int, nreq int) (int, error)
- func (m *Manager) RequeueCmp(c Checker, addr uintptr, val uint32, naddr uintptr, nwake int, nreq int) (int, error)
- func (m *Manager) WaitComplete(w *Waiter)
- func (m *Manager) WaitPrepare(w *Waiter, c Checker, addr uintptr, val uint32, bitmask uint32) error
- func (m *Manager) Wake(addr uintptr, bitmask uint32, n int) (int, error)
- func (m *Manager) WakeOp(c Checker, addr1 uintptr, addr2 uintptr, nwake1 int, nwake2 int, op uint32) (int, error)
- type Waiter
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Checker ¶
type Checker interface { // Check should validate that given address contains the given value. // If it does not contain the value, syserror.EAGAIN must be returned. // Any other error may be returned, which will be propagated. Check(addr uintptr, val uint32) error // Op should atomically perform the operation encoded in op on the data // pointed to by addr, then apply the comparison encoded in op to the // original value at addr, returning the result. // Note that op is an opaque operation whose behaviour is defined // outside of the futex manager. Op(addr uintptr, op uint32) (bool, error) }
Checker abstracts memory accesses. This is useful because the "addresses" used in this package may not be real addresses (they could be indices of an array, for example), or they could be mapped via some special mechanism.
TODO: Replace this with usermem.IO.
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager holds futex state for a single virtual address space.
func NewManager ¶
func NewManager() *Manager
NewManager returns an initialized futex manager. N.B. we use virtual address to tag futexes, so it only works for private (within a single process) futex.
func (*Manager) Requeue ¶
Requeue wakes up to nwake waiters on the given addr, and unconditionally requeues up to nreq waiters on naddr.
func (*Manager) RequeueCmp ¶
func (m *Manager) RequeueCmp(c Checker, addr uintptr, val uint32, naddr uintptr, nwake int, nreq int) (int, error)
RequeueCmp atomically checks that the addr contains val (via the Checker), wakes up to nwake waiters on addr and then unconditionally requeues nreq waiters on naddr.
func (*Manager) WaitComplete ¶
WaitComplete must be called when a Waiter previously added by WaitPrepare is no longer eligible to be woken.
func (*Manager) WaitPrepare ¶
WaitPrepare atomically checks that addr contains val (via the Checker), then enqueues w to be woken by a send to w.C. If WaitPrepare returns nil, the Waiter must be subsequently removed by calling WaitComplete, whether or not a wakeup is received on w.C.
func (*Manager) Wake ¶
Wake wakes up to n waiters matching the bitmask on the given addr. The number of waiters woken is returned.
func (*Manager) WakeOp ¶
func (m *Manager) WakeOp(c Checker, addr1 uintptr, addr2 uintptr, nwake1 int, nwake2 int, op uint32) (int, error)
WakeOp atomically applies op to the memory address addr2, wakes up to nwake1 waiters unconditionally from addr1, and, based on the original value at addr2 and a comparison encoded in op, wakes up to nwake2 waiters from addr2. It returns the total number of waiters woken.
type Waiter ¶
type Waiter struct { // C is sent to when the Waiter is woken. C chan struct{} // contains filtered or unexported fields }
Waiter is the struct which gets enqueued into buckets for wake up routines and requeue routines to scan and notify. Once a Waiter has been enqueued by WaitPrepare(), callers may listen on C for wake up events.