-
Notifications
You must be signed in to change notification settings - Fork 13
/
setup.go
140 lines (127 loc) · 3.94 KB
/
setup.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package gouring
import (
"syscall"
"unsafe"
)
// func io_uring_queue_init(entries uint32, ring *IoUring, flags uint32) error {
// p := new(IoUringParams)
// p.Flags = flags
// return io_uring_queue_init_params(entries, ring, p)
// }
func io_uring_queue_init_params(entries uint32, ring *IoUring, p *IoUringParams) error {
fd, err := io_uring_setup(uintptr(entries), p)
if err != nil {
return err
}
err = io_uring_queue_mmap(fd, p, ring)
if err != nil {
return err
}
ring.Features = p.Features
return nil
}
func (ring *IoUring) io_uring_queue_exit() {
sq := &ring.Sq
cq := &ring.Cq
sqeSize := SizeofIoUringSqe
if ring.Flags&IORING_SETUP_SQE128 != 0 {
sqeSize += 64
}
munmap(unsafe.Pointer(sq.Sqes), sqeSize*uintptr(*sq._RingEntries()))
io_uring_unmap_rings(sq, cq)
/*
* Not strictly required, but frees up the slot we used now rather
* than at process exit time.
*/
if ring.IntFlags&INT_FLAG_REG_RING != 0 {
ring.io_uring_unregister_ring_fd()
}
syscall.Close(int(ring.RingFd))
}
func io_uring_queue_mmap(fd int, p *IoUringParams, ring *IoUring) error {
err := io_uring_mmap(fd, p, &ring.Sq, &ring.Cq)
if err != nil {
return err
}
ring.Flags = p.Flags
ring.RingFd, ring.EnterRingFd = fd, fd
ring.IntFlags = 0
return nil
}
func io_uring_mmap(fd int, p *IoUringParams, sq *IoUringSq, cq *IoUringCq) (err error) {
size := SizeofIoUringCqe
if p.Flags&IORING_SETUP_CQE32 != 0 {
size += SizeofIoUringCqe
}
sq.RingSz = p.SqOff.Array + p.SqEntries*uint32(SizeofUnsigned)
cq.RingSz = p.CqOff.Cqes + p.CqEntries*uint32(size)
if p.Features&IORING_FEAT_SINGLE_MMAP != 0 {
if cq.RingSz > sq.RingSz {
sq.RingSz = cq.RingSz
}
// cq.RingSz = sq.RingSz
}
// alloc sq ring
sq.RingPtr, err = mmap(nil, uintptr(sq.RingSz),
syscall.PROT_READ|syscall.PROT_WRITE,
syscall.MAP_SHARED|syscall.MAP_POPULATE,
fd, IORING_OFF_SQ_RING)
if err != nil {
return
}
if p.Features&IORING_FEAT_SINGLE_MMAP != 0 {
cq.RingPtr = sq.RingPtr
} else {
// alloc cq ring
cq.RingPtr, err = mmap(nil, uintptr(cq.RingSz),
syscall.PROT_READ|syscall.PROT_WRITE,
syscall.MAP_SHARED|syscall.MAP_POPULATE,
fd, IORING_OFF_CQ_RING)
if err != nil {
// goto errLabel
io_uring_unmap_rings(sq, cq)
return
}
}
//sq
sq.head = (unsafe.Pointer(uintptr(sq.RingPtr) + uintptr(p.SqOff.Head)))
sq.tail = (unsafe.Pointer(uintptr(sq.RingPtr) + uintptr(p.SqOff.Tail)))
sq.ringMask = (unsafe.Pointer(uintptr(sq.RingPtr) + uintptr(p.SqOff.RingMask)))
sq.ringEntries = (unsafe.Pointer(uintptr(sq.RingPtr) + uintptr(p.SqOff.RingEntries)))
sq.flags = (unsafe.Pointer(uintptr(sq.RingPtr) + uintptr(p.SqOff.Flags)))
sq.dropped = (unsafe.Pointer(uintptr(sq.RingPtr) + uintptr(p.SqOff.Dropped)))
sq.Array = (uint32Array)(unsafe.Pointer(uintptr(sq.RingPtr) + uintptr(p.SqOff.Array)))
size = SizeofIoUringSqe
if p.Flags&IORING_SETUP_SQE128 != 0 {
size += 64
}
var sqeAddr unsafe.Pointer
sqeAddr, err = mmap(nil, size*uintptr(p.SqEntries),
syscall.PROT_READ|syscall.PROT_WRITE,
syscall.MAP_SHARED|syscall.MAP_POPULATE,
fd, IORING_OFF_SQES)
if err != nil {
//errLabel:
io_uring_unmap_rings(sq, cq)
return
}
sq.Sqes = (ioUringSqeArray)(sqeAddr)
//cq
cq.head = (unsafe.Pointer(uintptr(cq.RingPtr) + uintptr(p.CqOff.Head)))
cq.tail = (unsafe.Pointer(uintptr(cq.RingPtr) + uintptr(p.CqOff.Tail)))
cq.ringMask = (unsafe.Pointer(uintptr(cq.RingPtr) + uintptr(p.CqOff.RingMask)))
cq.ringEntries = (unsafe.Pointer(uintptr(cq.RingPtr) + uintptr(p.CqOff.RingEntries)))
cq.overflow = (unsafe.Pointer(uintptr(cq.RingPtr) + uintptr(p.CqOff.Overflow)))
cq.Cqes = (ioUringCqeArray)(unsafe.Pointer(uintptr(cq.RingPtr) + uintptr(p.CqOff.Cqes)))
if p.CqOff.Flags != 0 {
cq.flags = (unsafe.Pointer(uintptr(cq.RingPtr) + uintptr(p.CqOff.Flags)))
}
return nil
}
func io_uring_unmap_rings(sq *IoUringSq, cq *IoUringCq) error {
munmap(sq.RingPtr, uintptr(sq.RingSz))
if cq.RingPtr != nil && cq.RingPtr != sq.RingPtr {
munmap(cq.RingPtr, uintptr(cq.RingSz))
}
return nil
}