README

io_uring Go

GoDoc

WORK IN PROGRESS This library adds support for io_uring for Go. This library is similar to liburing. If you want to contribute feel free to send PRs or emails, there's plenty of things that need cleaned up. Also, check out @dshylyak's uring library as well for a similar approach. Ideally, these approaches would be added to the Go runtime for optimal efficiency, so these libraries are more of a POC, see here.

Interacting with the Submit/Completion Queues

Design

The library is designed so that if you want to use your own implementation for handling submissions/completions that everything is available for use. Alternatively, there helper methods on the Ring struct that also interact with standard library interfaces as well. There is also a interface for creating a net.Listener, but it is still a work in progress.

Submission Queue

The submission and completion queues are both mmap'd as slices, the question then becomes how to design an efficient API that is also able to interact with many of the standard library interfaces. One choice is to run a background goroutine that manages all operations with the queues and use channels for enqueuing requests. The downside of this approach is that are outstanding issues with the design of channels may make it suboptimal for high throughput IO.

liburing uses memory barriers for interacting appropriately with the submission/completion queues of io_uring. One problem with the memory model of Go is that it uses weak atomics which can make it difficult to use sync/atomic in all situations. If certain IO operations are to be carriered out in a specific order then this becomes a real challenge.

The current challenge with the SQ is that currently for each reader/writer interface every time the a read or write is submitted the Enter method is called on the ring. These could be batched (with a small latency penalty) and allow for a single enter of the ring, which would result in fewer syscalls.

Completion Queue

Completion queues have the difficulty of many concurrent readers which need to synchronize updating the position of the head. The current solution is to have a separate background goroutine that tracks the position of the out of order completions and updates the head as necessary. This separates the logic of synchronizing updating of the CQ head and handling a SQ request

Setup

Ulimit values for locked memory address space may need to be adjusted. If the following error occurs when running tests then the memlock value in /etc/security/limits.conf may need to be increased.

=== RUN   TestNew
    TestNew: ring_test.go:13:
                Error Trace:    ring_test.go:13
                Error:          Received unexpected error:
                                cannot allocate memory
                Test:           TestNew

The ulimit value must be greater than the ring size, use ulimit -l to view the current limit.

Example

Here is a minimal example to get started that writes to a file using a ring:

package main

import (
	"log"
	"os"

	"github.com/hodgesds/iouring-go"
)

func main() {
	r, err := iouring.New(1024, &iouring.Params{
		Features: iouring.FeatNoDrop,
	})
	if err != nil {
		log.Fatal(err)
	}

	// Open a file for registering with the ring.
	f, err := os.OpenFile("hello.txt", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755)
	if err != nil {
		log.Fatal(err)
	}

	// Register the file with the ring, which returns an io.WriteCloser.
	rw, err := r.FileReadWriter(f)
	if err != nil {
		log.Fatal(err)
	}

	if _, err := rw.Write([]byte("hello io_uring!")); err != nil {
		log.Fatal(err)
	}

	// Close the WriteCloser, which closes the open file (f).
	if err := r.Close(); err != nil {
		log.Fatal(err)
	}
}

Benchmarks

I haven't really wanted to add any benchmarks as I haven't spent the time to really write good benchmarks. However, here's some initial numbers with some comments:

BenchmarkFileWrite
BenchmarkFileWrite/os-file-write-128
BenchmarkFileWrite/os-file-write-128-8                    245845              4649 ns/op          27.53 MB/s           0 B/op          0 allocs/op
BenchmarkFileWrite/os-file-write-512
BenchmarkFileWrite/os-file-write-512-8                    243472              4867 ns/op         105.20 MB/s           0 B/op          0 allocs/op
BenchmarkFileWrite/os-file-write-1024
BenchmarkFileWrite/os-file-write-1024-8                   212593              5320 ns/op         192.48 MB/s           0 B/op          0 allocs/op
BenchmarkFileWrite/os-file-write-2048
BenchmarkFileWrite/os-file-write-2048-8                   183775              6047 ns/op         338.69 MB/s           0 B/op          0 allocs/op
BenchmarkFileWrite/os-file-write-4096
BenchmarkFileWrite/os-file-write-4096-8                   143608              7614 ns/op         537.98 MB/s           0 B/op          0 allocs/op
BenchmarkRingWrite
BenchmarkRingWrite/ring-1024-write-128
BenchmarkRingWrite/ring-1024-write-128-8                  126456              9346 ns/op          13.70 MB/s          32 B/op          1 allocs/op
BenchmarkRingWrite/ring-1024-write-512
BenchmarkRingWrite/ring-1024-write-512-8                  119118             10702 ns/op          47.84 MB/s          32 B/op          1 allocs/op
BenchmarkRingWrite/ring-1024-write-1024
BenchmarkRingWrite/ring-1024-write-1024-8                 115423             10600 ns/op          96.60 MB/s          32 B/op          1 allocs/op
BenchmarkRingWrite/ring-8192-write-2048
BenchmarkRingWrite/ring-8192-write-2048-8                 103276             11006 ns/op         186.07 MB/s          32 B/op          1 allocs/op
BenchmarkRingWrite/ring-8192-write-4096
BenchmarkRingWrite/ring-8192-write-4096-8                  87127             13704 ns/op         298.90 MB/s          32 B/op          1 allocs/op
BenchmarkRingDeadlineWrite
BenchmarkRingDeadlineWrite/ring-1024-deadline-1ms-128
BenchmarkRingDeadlineWrite/ring-1024-deadline-1ms-128-8                   102620              9979 ns/op          12.83 MB/s          32 B/op          1 allocs/op
BenchmarkRingDeadlineWrite/ring-1024-deadline-100µs-512
BenchmarkRingDeadlineWrite/ring-1024-deadline-100µs-512-8                 118021             10479 ns/op          48.86 MB/s          32 B/op          1 allocs/op
BenchmarkRingDeadlineWrite/ring-1024-deadline-10µs-1024
BenchmarkRingDeadlineWrite/ring-1024-deadline-10µs-1024-8                 103600             10232 ns/op         100.08 MB/s          32 B/op          1 allocs/op
BenchmarkRingDeadlineWrite/ring-8192-deadline-1µs-2048
BenchmarkRingDeadlineWrite/ring-8192-deadline-1µs-2048-8                  101726             11330 ns/op         180.75 MB/s          32 B/op          1 allocs/op
BenchmarkRingDeadlineWrite/ring-8192-deadline-1µs-4096
BenchmarkRingDeadlineWrite/ring-8192-deadline-1µs-4096-8                   87483             13547 ns/op         302.35 MB/s          32 B/op          1 allocs/op
BenchmarkRingMultiWrite
    BenchmarkRingMultiWrite: ring_benchmark_test.go:207: 

The first benchmark is just regualar os.File Write calls. This benchmark was run on Xeon E3-1505M v5 running on a luks encrypted consumer NVMe drive. The first thing to note is that the ns/op for for increasing write sizes scales from 4-8k. That seems pretty reasonable because the runtime is taking care of handling the system call.

The BenchmarkRingWrite is roughly the same type of benchmark with an Enter being called for each SQE (essentially 1 syscall per write request). Note, that the ns/op is much higher because of all extra "stuff" the ring is handling. It also has a single allocation because it uses a monotonically increasing request id for tracking submissions with completions (using the user data field in the SQE). The other thing to note is the ring currently isn't using an eventfd for handling completions, it is doing the good old fashion brute force approach of submitting the request and then aggressively checking the CQ for the completion event. This is rather ineficient and burns some CPU cycles. Switching to an eventfd approach would probably be the ideal way to solve this problem. So the numbers showing roughly double the ns/op are pretty reasonable given the current design, which explains the lower throughput when doing a '1:1' comparison with Go file IO.

The BenchmarkRingDeadlineWrite is kind of similar to the BenchmarkRingWrite only it uses a deadline approach for submissions. This in theory should handle concurrent writes far better, but there is no benchmark that is using concurrent writes as it is not the easiest type benchmark to write.

The multiwrite API is still a WIP and it in theory should allow for "fan out" style writes to multiple FDs.

Note, this library is still usable to a point where you can come up with your own concurrent io scheduling based on whatever huerestics you want (limiting IO requests per user?!?!). Implementing the perfect IO scheduler for Go is not really a goal of this project so this library will most likely have some tradeoffs (ie. my spare time) when it comes to optimal scheduling algorithms. If you are interested in this area feel free to send any PRs.

Interacting with the SQ

The submission queue can be interacted with by using the SubmitEntry method on a Ring. The returned function must be called after all updates to the SubmitEntry are complete and before the ring is entered. The callback is used for synchronization across goroutines.

Other References

https://cor3ntin.github.io/posts/iouring/

https://github.com/google/vectorio

https://github.com/shuveb/io_uring-by-example/blob/master/02_cat_uring/main.c

https://golang.org/pkg/syscall/#Iovec

https://github.com/golang/go/blob/master/src/runtime/mbarrier.go#L21

Expand ▾ Collapse ▴

Documentation

Index

Constants

View Source
const (
	POLLIN   = 0x1
	POLLPRI  = 0x2
	POLLOUT  = 0x4
	POLLERR  = 0x8
	POLLHUP  = 0x10
	POLLNVAL = 0x20

	// SOReuseport is the socket option to reuse socket port.
	SOReuseport int = 0x0F

	// TCPFastopen is the socket option to open a TCP fast open.
	TCPFastopen int = 0x17
)
View Source
const (
	// SetupSyscall defines the syscall number for io_uring_setup.
	SetupSyscall = 425
	// EnterSyscall defines the syscall number for io_uring_enter.
	EnterSyscall = 426
	// RegisterSyscall defines the syscall number for io_uring_register.
	RegisterSyscall = 427
)
View Source
const (

	// FeatSingleMmap is used to configure a single mmap'd ring.
	FeatSingleMmap = (1 << 0)
	// FeatNoDrop is used to ensure that no CQEs are dropped.
	FeatNoDrop         = (1 << 1)
	FeatSubmitStable   = (1 << 2)
	FeatRwCurPos       = (1 << 3)
	FeatCurPersonality = (1 << 4)
)
View Source
const (
	/*
	 * sqe->flags
	 */
	SqeFixedFileBit = iota
	SqeIoDrainBit
	SqeIoLinkBit
	SqeIoHardlinkBit
	SqeAsyncBit
	SqeBufferSelectBit

	// SqeFixedFile use fixed fileset
	SqeFixedFile uint8 = (1 << SqeFixedFileBit)
	// SqeIoDrain issue after inflight IO
	SqeIoDrain uint8 = (1 << SqeIoDrainBit)
	// SqeIoLink is used to link multiple SQEs.
	SqeIoLink uint8 = (1 << SqeIoLinkBit)
	// SqeIoHardlink is a hard link to multiple SQEs
	SqeIoHardlink uint8 = (1 << SqeIoHardlinkBit)
	// SqeAsync is use to specify async io.
	SqeAsync uint8 = (1 << SqeAsyncBit)
	// SqeBufferSelect is used to specify buffer select.
	SqeBufferSelect uint8 = (1 << SqeBufferSelectBit)

	// SetupIOPoll io_context is polled
	SetupIOPoll uint32 = (1 << 0)
	// SetupSQPoll SQ poll thread
	SetupSQPoll uint32 = (1 << 1)
	// SetupSQAFF sq_thread_cpu is valid
	SetupSQAFF uint32 = (1 << 2)
	// SetupCqSize app defines CQ size
	SetupCqSize uint32 = (1 << 3)
	// SetupClamp clamp SQ/CQ ring sizes
	SetupClamp uint32 = (1 << 4)
	// SetupAttachWq  attach to existing wq
	SetupAttachWq uint32 = (1 << 5)
)
View Source
const (

	// FsyncDatasync ...
	FsyncDatasync uint = (1 << 0)

	// SqRingOffset is the offset of the submission queue.
	SqRingOffset uint64 = 0
	// CqRingOffset is the offset of the completion queue.
	CqRingOffset uint64 = 0x8000000
	// SqeRingOffset is the offset of the submission queue entries.
	SqeRingOffset uint64 = 0x10000000

	// SqNeedWakeup needs io_uring_enter wakeup
	SqNeedWakeup uint32 = (1 << 0)
	SqCqOverflow uint32 = (1 << 1)

	// EnterGetEvents ...
	EnterGetEvents uint = (1 << 0)
	// EnterSqWakeup ...
	EnterSqWakeup uint = (1 << 1)

	RegRegisterBuffers       = 0
	RegUnregisterBuffers     = 1
	RegRegisterFiles         = 2
	RegUnregisterFiles       = 3
	RegRegisterEventFd       = 4
	RegUnregisterEventfd     = 5
	RegRegisterFilesUpdate   = 6
	RegRegisterEventFdAsync  = 7
	RegRegisterProbe         = 8
	RegRegisterPersonality   = 9
	RegUnregisterPersonality = 10
)
View Source
const (
	// CqSeenFlag is a nonstandard flag for handling concurrent readers
	// from the CompletionQueue.
	CqSeenFlag = 1
)

Variables

View Source
var (
	// ErrEntryNotFound is returned when a CQE is not found.
	ErrEntryNotFound = errors.New("Completion entry not found")
)

Functions

func Enter

func Enter(fd int, toSubmit uint, minComplete uint, flags uint, sigset *unix.Sigset_t) (int, error)

    Enter is used to submit to the queue.

    func FastOpenAllowed

    func FastOpenAllowed() error

      FastOpenAllowed return nil if fast open is enabled.

      func MmapRing

      func MmapRing(fd int, p *Params, sq *SubmitQueue, cq *CompletionQueue) error

        MmapRing is used to configure the submit and completion queues, it should only be called after the Setup function has completed successfully. See: https://github.com/axboe/liburing/blob/master/src/setup.c#L22

        func RegisterBuffers

        func RegisterBuffers(fd int, vecs []*syscall.Iovec) error

          RegisterBuffers is used to register buffers to a ring.

          func RegisterEventFd

          func RegisterEventFd(ringFd int, fd int) error

            RegisterEventFd is used to register an event file descriptor to a ring.

            func RegisterEventFdAsync

            func RegisterEventFdAsync(ringFd int, fd int) error

              RegisterEventFdAsync is used to register an event file descriptor for async polling on a ring.

              func RegisterFiles

              func RegisterFiles(fd int, files []int) error

                RegisterFiles is used to register files to a ring.

                func ReregisterFiles

                func ReregisterFiles(fd int, files []int) error

                  ReregisterFiles is used to reregister files to a ring.

                  func Setup

                  func Setup(entries uint, params *Params) (int, error)

                    Setup is used to setup a io_uring using the io_uring_setup syscall.

                    func UnregisterBuffers

                    func UnregisterBuffers(fd int, vecs []*syscall.Iovec) error

                      UnregisterBuffers is used to unregister iovecs from a ring.

                      func UnregisterEventFd

                      func UnregisterEventFd(ringFd int, fd int) error

                        UnregisterEventFd is used to unregister a file descriptor to a ring.

                        func UnregisterFiles

                        func UnregisterFiles(fd int, files []int) error

                          UnregisterFiles is used to unregister files to a ring.

                          Types

                          type CQRingOffset

                          type CQRingOffset struct {
                          	Head     uint32
                          	Tail     uint32
                          	RingMask uint32
                          	Entries  uint32
                          	Overflow uint32
                          	Cqes     uint32
                          	Flags    uint32
                          	Resv     [2]uint64
                          }

                            CQRingOffset describes the various completion queue offsets.

                            type CompletionEntry

                            type CompletionEntry struct {
                            	UserData uint64 /* sqe->data submission data passed back */
                            	Res      int32  /* result code for this event */
                            	Flags    uint32
                            }

                              CompletionEntry IO completion data structure (Completion Queue Entry).

                              func (*CompletionEntry) IsZero

                              func (c *CompletionEntry) IsZero() bool

                                IsZero returns if the CQE is zero valued.

                                type CompletionQueue

                                type CompletionQueue struct {
                                	Size     uint32
                                	Head     *uint32
                                	Tail     *uint32
                                	Mask     *uint32
                                	Overflow *uint32
                                	Flags    *uint32
                                
                                	// Entries must never be resized, it is mmap'd.
                                	Entries []CompletionEntry
                                	// contains filtered or unexported fields
                                }

                                  CompletionQueue represents the completion queue ring buffer.

                                  func (*CompletionQueue) Advance

                                  func (c *CompletionQueue) Advance(count int)

                                    Advance is used to advance the completion queue by a count.

                                    func (*CompletionQueue) EntryBy

                                    func (c *CompletionQueue) EntryBy(userData uint64) (*CompletionEntry, error)

                                      EntryBy (DEPRECATED) returns a CompletionEntry by comparing the user data, this should be called after the ring has been entered.

                                      type FileRegistry

                                      type FileRegistry interface {
                                      	Register(int) error
                                      	Unregister(int) error
                                      	ID(int) (int, bool)
                                      }

                                        FileRegistry is an interface for registering files to a Ring.

                                        func NewFileRegistry

                                        func NewFileRegistry(ringFd int) FileRegistry

                                          NewFileRegistry creates a FileRegistry for use with a ring.

                                          type Opcode

                                          type Opcode uint8

                                            Opcode is an opcode for the ring.

                                            const (
                                            	Nop Opcode = iota
                                            	Readv
                                            	Writev
                                            	Fsync
                                            	ReadFixed
                                            	WriteFixed
                                            	PollAdd
                                            	PollRemove
                                            	SyncFileRange
                                            	SendMsg
                                            	RecvMsg
                                            	Timeout
                                            	TimeoutRemove
                                            	Accept
                                            	AsyncCancel
                                            	LinkTimeout
                                            	Connect
                                            	Fallocate
                                            	OpenAt
                                            	Close
                                            	FilesUpdate
                                            	Statx
                                            	Read
                                            	Write
                                            	Fadvise
                                            	Madvise
                                            	Send
                                            	Recv
                                            	Openat2
                                            	EpollCtl
                                            	Splice
                                            	ProvideBuffers
                                            	RemoveBuffers
                                            	OpSupported = (1 << 0)
                                            )

                                            type Params

                                            type Params struct {
                                            	SqEntries    uint32
                                            	CqEntries    uint32
                                            	Flags        uint32
                                            	SqThreadCPU  uint32
                                            	SqThreadIdle uint32
                                            	Features     uint32
                                            	WqFD         uint32
                                            	Resv         [3]uint32
                                            	SqOffset     SQRingOffset
                                            	CqOffset     CQRingOffset
                                            }

                                              Params are used to configured a io uring.

                                              type ReadWriteAtCloser

                                              type ReadWriteAtCloser interface {
                                              	io.WriterAt
                                              	io.ReadWriteCloser
                                              }

                                                ReadWriteAtCloser supports reading, writing, and closing.

                                                type ReadWriteSeekerCloser

                                                type ReadWriteSeekerCloser interface {
                                                	io.Reader
                                                	io.Writer
                                                	io.Seeker
                                                	io.Closer
                                                	ReadAt([]byte, int64) (int, error)
                                                	WriteAt([]byte, int64) (int, error)
                                                }

                                                  ReadWriteSeekerCloser is a ReadWriteCloser and ReadWriteSeeker.

                                                  type Ring

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

                                                    Ring contains an io_uring submit and completion ring.

                                                    func New

                                                    func New(size uint, p *Params, opts ...RingOption) (*Ring, error)

                                                      New is used to create an iouring.Ring.

                                                      func (*Ring) CQ

                                                      func (r *Ring) CQ() *CompletionQueue

                                                        CQ returns the CompletionQueue for the ring.

                                                        func (*Ring) CanEnter

                                                        func (r *Ring) CanEnter() bool

                                                          CanEnter returns whether or not the ring can be entered.

                                                          func (*Ring) Close

                                                          func (r *Ring) Close(fd int) error

                                                            Close is implements close(2).

                                                            func (*Ring) CompleteHead

                                                            func (r *Ring) CompleteHead() int

                                                              CompleteHead returns the position of the head of the completion queue. This method is safe for calling concurrently.

                                                              func (*Ring) CompleteTail

                                                              func (r *Ring) CompleteTail() int

                                                                CompleteTail returns the position of the tail of the submit queue. This method is safe for calling concurrently.

                                                                func (*Ring) Enter

                                                                func (r *Ring) Enter(toSubmit uint, minComplete uint, flags uint, sigset *unix.Sigset_t) (int, error)

                                                                  Enter is used to enter the ring.

                                                                  func (*Ring) EventFd

                                                                  func (r *Ring) EventFd() int

                                                                    EventFd returns the file descriptor of the eventfd if it is set, otherwise it returns the default value of -1.

                                                                    func (*Ring) Fadvise

                                                                    func (r *Ring) Fadvise(fd int, offset uint64, n uint32, advise int) error

                                                                      Fadvise implements fadvise.

                                                                      func (*Ring) Fallocate

                                                                      func (r *Ring) Fallocate(fd int, mode uint32, offset int64, n int64) error

                                                                        Fallocate implements fallocate.

                                                                        func (*Ring) Fd

                                                                        func (r *Ring) Fd() int

                                                                          Fd returns the file descriptor of the ring.

                                                                          func (*Ring) FileReadWriter

                                                                          func (r *Ring) FileReadWriter(f *os.File) (ReadWriteSeekerCloser, error)

                                                                            FileReadWriter returns an io.ReadWriter from an os.File that uses the ring. Note that is is not valid to use other operations on the file (Seek/Close) in combination with the reader.

                                                                            func (*Ring) FileRegistry

                                                                            func (r *Ring) FileRegistry() FileRegistry

                                                                              FileRegistry returns the FileRegistry for the Ring.

                                                                              func (*Ring) Fsync

                                                                              func (r *Ring) Fsync(fd int, flags int) error

                                                                                Fsync implements fsync(2).

                                                                                func (*Ring) ID

                                                                                func (r *Ring) ID() uint64

                                                                                  ID returns an id for a SQEs, it is a monotonically increasing value (until uint64 wrapping).

                                                                                  func (*Ring) NeedsEnter

                                                                                  func (r *Ring) NeedsEnter() bool

                                                                                    NeedsEnter returns if the ring needs to be entered.

                                                                                    func (*Ring) Nop

                                                                                    func (r *Ring) Nop() error

                                                                                      Nop is a nop.

                                                                                      func (*Ring) PollAdd

                                                                                      func (r *Ring) PollAdd(fd int, mask int) error

                                                                                        PollAdd is used to add a poll to a fd.

                                                                                        func (*Ring) PrepareAccept

                                                                                        func (r *Ring) PrepareAccept(
                                                                                        	fd int,
                                                                                        	addr syscall.Sockaddr,
                                                                                        	socklen uint32,
                                                                                        	flags int,
                                                                                        ) (uint64, error)

                                                                                          PrepareAccept is used to prepare a SQE for an accept(2) call.

                                                                                          func (*Ring) PrepareClose

                                                                                          func (r *Ring) PrepareClose(fd int) (uint64, error)

                                                                                            PrepareClose is used to prepare a close(2) call.

                                                                                            func (*Ring) PrepareConnect

                                                                                            func (r *Ring) PrepareConnect(
                                                                                            	fd int,
                                                                                            	addr syscall.Sockaddr,
                                                                                            	socklen uint32,
                                                                                            ) (uint64, error)

                                                                                              PrepareConnect is used to prepare a SQE for a connect(2) call.

                                                                                              func (*Ring) PrepareFadvise

                                                                                              func (r *Ring) PrepareFadvise(
                                                                                              	fd int, offset uint64, n uint32, advise int) (uint64, error)

                                                                                                PrepareFadvise is used to prepare a fadvise call.

                                                                                                func (*Ring) PrepareFallocate

                                                                                                func (r *Ring) PrepareFallocate(
                                                                                                	fd int, mode uint32, offset int64, n int64) (uint64, error)

                                                                                                  PrepareFallocate is used to prepare a fallocate call.

                                                                                                  func (*Ring) PrepareFsync

                                                                                                  func (r *Ring) PrepareFsync(fd int, flags int) (uint64, error)

                                                                                                    PrepareFsync is used to prepare a fsync(2) call.

                                                                                                    func (*Ring) PrepareNop

                                                                                                    func (r *Ring) PrepareNop() (uint64, error)

                                                                                                      PrepareNop is used to prep a nop.

                                                                                                      func (*Ring) PreparePollAdd

                                                                                                      func (r *Ring) PreparePollAdd(fd int, mask int) (uint64, error)

                                                                                                        PreparePollAdd is used to prepare a SQE for adding a poll.

                                                                                                        func (*Ring) PrepareRead

                                                                                                        func (r *Ring) PrepareRead(
                                                                                                        	fd int,
                                                                                                        	b []byte,
                                                                                                        	offset uint64,
                                                                                                        	flags uint8,
                                                                                                        ) (uint64, error)

                                                                                                          PrepareRead is used to prepare a read SQE.

                                                                                                          func (*Ring) PrepareReadFixed

                                                                                                          func (r *Ring) PrepareReadFixed(
                                                                                                          	fd int,
                                                                                                          	b []byte,
                                                                                                          	flags uint8,
                                                                                                          ) (uint64, error)

                                                                                                            PrepareReadFixed is used to prepare a fixed read SQE.

                                                                                                            func (*Ring) PrepareReadv

                                                                                                            func (r *Ring) PrepareReadv(
                                                                                                            	fd int,
                                                                                                            	iovecs []*syscall.Iovec,
                                                                                                            	offset int,
                                                                                                            ) (uint64, error)

                                                                                                              PrepareReadv is used to prepare a readv SQE.

                                                                                                              func (*Ring) PrepareRecv

                                                                                                              func (r *Ring) PrepareRecv(
                                                                                                              	fd int,
                                                                                                              	b []byte,
                                                                                                              	flags uint8,
                                                                                                              ) (uint64, error)

                                                                                                                PrepareRecv is used to prepare a Recv SQE.

                                                                                                                func (*Ring) PrepareRecvmsg

                                                                                                                func (r *Ring) PrepareRecvmsg(
                                                                                                                	fd int,
                                                                                                                	msg *syscall.Msghdr,
                                                                                                                	flags int,
                                                                                                                ) (uint64, error)

                                                                                                                  PrepareRecvmsg is used to prepare a recvmsg SQE.

                                                                                                                  func (*Ring) PrepareSend

                                                                                                                  func (r *Ring) PrepareSend(
                                                                                                                  	fd int,
                                                                                                                  	b []byte,
                                                                                                                  	flags uint8,
                                                                                                                  ) (uint64, error)

                                                                                                                    PrepareSend is used to prepare a Send SQE.

                                                                                                                    func (*Ring) PrepareSplice

                                                                                                                    func (r *Ring) PrepareSplice(
                                                                                                                    	inFd int,
                                                                                                                    	inOff *int64,
                                                                                                                    	outFd int,
                                                                                                                    	outOff *int64,
                                                                                                                    	n int,
                                                                                                                    	flags int,
                                                                                                                    ) (uint64, error)

                                                                                                                      PrepareSplice is used to prepare a SQE for a splice(2).

                                                                                                                      func (*Ring) PrepareStatx

                                                                                                                      func (r *Ring) PrepareStatx(
                                                                                                                      	dirfd int,
                                                                                                                      	path string,
                                                                                                                      	flags int,
                                                                                                                      	mask int,
                                                                                                                      	statx *unix.Statx_t,
                                                                                                                      ) (uint64, error)

                                                                                                                        PrepareStatx is used to prepare a Statx call and will return the request id (SQE UserData) of the SQE. After calling the returned callback function the ring is safe to be entered.

                                                                                                                        func (*Ring) PrepareTimeout

                                                                                                                        func (r *Ring) PrepareTimeout(
                                                                                                                        	ts *syscall.Timespec, count int, flags int) (uint64, error)

                                                                                                                          PrepareTimeout is used to prepare a timeout SQE.

                                                                                                                          func (*Ring) PrepareTimeoutRemove

                                                                                                                          func (r *Ring) PrepareTimeoutRemove(data uint64, flags int) (uint64, error)

                                                                                                                            PrepareTimeoutRemove is used to prepare a timeout removal.

                                                                                                                            func (*Ring) PrepareWrite

                                                                                                                            func (r *Ring) PrepareWrite(
                                                                                                                            	fd int,
                                                                                                                            	b []byte,
                                                                                                                            	offset uint64,
                                                                                                                            	flags uint8,
                                                                                                                            ) (uint64, error)

                                                                                                                              PrepareWrite is used to prepare a Write SQE.

                                                                                                                              func (*Ring) PrepareWriteFixed

                                                                                                                              func (r *Ring) PrepareWriteFixed(
                                                                                                                              	fd int,
                                                                                                                              	b []byte,
                                                                                                                              	flags uint8,
                                                                                                                              ) (uint64, error)

                                                                                                                                PrepareWriteFixed is used to prepare a fixed write SQE.

                                                                                                                                func (*Ring) PrepareWritev

                                                                                                                                func (r *Ring) PrepareWritev(
                                                                                                                                	fd int,
                                                                                                                                	iovecs []*syscall.Iovec,
                                                                                                                                	offset int,
                                                                                                                                ) (uint64, error)

                                                                                                                                  PrepareWritev is used to prepare a writev SQE.

                                                                                                                                  func (*Ring) Recv

                                                                                                                                  func (r *Ring) Recv(
                                                                                                                                  	fd int,
                                                                                                                                  	b []byte,
                                                                                                                                  	flags uint8,
                                                                                                                                  ) error

                                                                                                                                    Recv is used to recv data on a socket.

                                                                                                                                    func (*Ring) SQ

                                                                                                                                    func (r *Ring) SQ() *SubmitQueue

                                                                                                                                      SQ returns the SubmitQueue for the ring.

                                                                                                                                      func (*Ring) Send

                                                                                                                                      func (r *Ring) Send(
                                                                                                                                      	fd int,
                                                                                                                                      	b []byte,
                                                                                                                                      	flags uint8,
                                                                                                                                      ) error

                                                                                                                                        Send is used to send data to a socket.

                                                                                                                                        func (*Ring) ShouldFlush

                                                                                                                                        func (r *Ring) ShouldFlush() bool

                                                                                                                                          ShouldFlush returns if the ring should flush due to cq being overflown.

                                                                                                                                          func (*Ring) SockoptListener

                                                                                                                                          func (r *Ring) SockoptListener(network, address string, errHandler func(error), sockopts ...int) (net.Listener, error)

                                                                                                                                            SockoptListener returns a net.Listener that is Ring based.

                                                                                                                                            func (*Ring) Splice

                                                                                                                                            func (r *Ring) Splice(
                                                                                                                                            	inFd int,
                                                                                                                                            	inOff *int64,
                                                                                                                                            	outFd int,
                                                                                                                                            	outOff *int64,
                                                                                                                                            	n int,
                                                                                                                                            	flags int,
                                                                                                                                            ) (int64, error)

                                                                                                                                              Splice implements splice using a ring.

                                                                                                                                              func (*Ring) Statx

                                                                                                                                              func (r *Ring) Statx(
                                                                                                                                              	dirfd int,
                                                                                                                                              	path string,
                                                                                                                                              	flags int,
                                                                                                                                              	mask int,
                                                                                                                                              	statx *unix.Statx_t,
                                                                                                                                              ) (err error)

                                                                                                                                                Statx implements statx using a ring.

                                                                                                                                                func (*Ring) Stop

                                                                                                                                                func (r *Ring) Stop() error

                                                                                                                                                  Stop is used to stop the ring.

                                                                                                                                                  func (*Ring) SubmitEntry

                                                                                                                                                  func (r *Ring) SubmitEntry() (*SubmitEntry, func())

                                                                                                                                                    SubmitEntry returns the next available SubmitEntry or nil if the ring is busy. The returned function should be called after SubmitEntry is ready to enter the ring.

                                                                                                                                                    func (*Ring) SubmitHead

                                                                                                                                                    func (r *Ring) SubmitHead() int

                                                                                                                                                      SubmitHead returns the position of the head of the submit queue. This method is safe for calling concurrently.

                                                                                                                                                      func (*Ring) SubmitTail

                                                                                                                                                      func (r *Ring) SubmitTail() int

                                                                                                                                                        SubmitTail returns the position of the tail of the submit queue. This method is safe for calling concurrently.

                                                                                                                                                        type RingOption

                                                                                                                                                        type RingOption func(*Ring) error

                                                                                                                                                          RingOption is an option for configuring a Ring.

                                                                                                                                                          func WithDeadline

                                                                                                                                                          func WithDeadline(d time.Duration) RingOption

                                                                                                                                                            WithDeadline is used to configure the deadline for submitting IO.

                                                                                                                                                            func WithDebug

                                                                                                                                                            func WithDebug() RingOption

                                                                                                                                                              WithDebug is used to print additional debug information.

                                                                                                                                                              func WithEnterErrHandler

                                                                                                                                                              func WithEnterErrHandler(f func(error)) RingOption

                                                                                                                                                                WithEnterErrHandler is used to handle errors on ring enter.

                                                                                                                                                                func WithEventFd

                                                                                                                                                                func WithEventFd(initval uint, flags int, async bool) RingOption

                                                                                                                                                                  WithEventFd is used to create an eventfd and register it to the Ring. The event fd can be accessed using the EventFd method.

                                                                                                                                                                  func WithFileRegistry

                                                                                                                                                                  func WithFileRegistry() RingOption

                                                                                                                                                                    WithFileRegistry is used to register a FileRegistry with the Ring. The registery can be accessed with the FileRegistry method on the ring.

                                                                                                                                                                    func WithID

                                                                                                                                                                    func WithID(id uint64) RingOption

                                                                                                                                                                      WithID is used to set the starting id for the monotonically increasing ID method.

                                                                                                                                                                      type SQRingOffset

                                                                                                                                                                      type SQRingOffset struct {
                                                                                                                                                                      	Head     uint32
                                                                                                                                                                      	Tail     uint32
                                                                                                                                                                      	RingMask uint32
                                                                                                                                                                      	Entries  uint32
                                                                                                                                                                      	Flags    uint32
                                                                                                                                                                      	Dropped  uint32
                                                                                                                                                                      	Array    uint32
                                                                                                                                                                      	Resv1    uint32
                                                                                                                                                                      	Resv2    uint64
                                                                                                                                                                      }

                                                                                                                                                                        SQRingOffset describes the various submit queue offsets.

                                                                                                                                                                        type SubmitEntry

                                                                                                                                                                        type SubmitEntry struct {
                                                                                                                                                                        	Opcode   Opcode /* type of operation for this sqe */
                                                                                                                                                                        	Flags    uint8  /* IOSQE_ flags */
                                                                                                                                                                        	Ioprio   uint16 /* ioprio for the request */
                                                                                                                                                                        	Fd       int32  /* file descriptor to do IO on */
                                                                                                                                                                        	Offset   uint64 /* offset into file */
                                                                                                                                                                        	Addr     uint64 /* pointer to buffer or iovecs */
                                                                                                                                                                        	Len      uint32 /* buffer size or number of iovecs */
                                                                                                                                                                        	UFlags   int32
                                                                                                                                                                        	UserData uint64
                                                                                                                                                                        	Anon0    [24]byte /* extra padding */
                                                                                                                                                                        }

                                                                                                                                                                          SubmitEntry is an IO submission data structure (Submission Queue Entry).

                                                                                                                                                                          func (*SubmitEntry) Reset

                                                                                                                                                                          func (e *SubmitEntry) Reset()

                                                                                                                                                                            Reset is used to reset an SubmitEntry.

                                                                                                                                                                            type SubmitQueue

                                                                                                                                                                            type SubmitQueue struct {
                                                                                                                                                                            	Size    uint32
                                                                                                                                                                            	Head    *uint32
                                                                                                                                                                            	Tail    *uint32
                                                                                                                                                                            	Mask    *uint32
                                                                                                                                                                            	Flags   *uint32
                                                                                                                                                                            	Dropped *uint32
                                                                                                                                                                            
                                                                                                                                                                            	// Array holds entries to be submitted; it must never be resized it is mmap'd.
                                                                                                                                                                            	Array []uint32
                                                                                                                                                                            	// Entries must never be resized, it is mmap'd.
                                                                                                                                                                            	Entries []SubmitEntry
                                                                                                                                                                            	// contains filtered or unexported fields
                                                                                                                                                                            }

                                                                                                                                                                              SubmitQueue represents the submit queue ring buffer.

                                                                                                                                                                              func (*SubmitQueue) NeedWakeup

                                                                                                                                                                              func (s *SubmitQueue) NeedWakeup() bool

                                                                                                                                                                                NeedWakeup is used to determine whether the submit queue needs awoken.

                                                                                                                                                                                func (*SubmitQueue) Reset

                                                                                                                                                                                func (s *SubmitQueue) Reset()

                                                                                                                                                                                  Reset is used to reset all entries.

                                                                                                                                                                                  Directories

                                                                                                                                                                                  Path Synopsis
                                                                                                                                                                                  examples
                                                                                                                                                                                  cp
                                                                                                                                                                                  net