mirror of
https://github.com/ii64/gouring.git
synced 2024-10-18 15:11:09 +02:00
fix(perf): direct field access
Signed-off-by: MastahSenpai <26342994+ii64@users.noreply.github.com>
This commit is contained in:
parent
6fb11e879d
commit
5937800f05
4 changed files with 60 additions and 115 deletions
8
core.go
8
core.go
|
@ -61,10 +61,10 @@ func (r *Ring) Fd() int {
|
||||||
return r.fd
|
return r.fd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Ring) SQ() *SQRing {
|
func (r *Ring) SQ() SQRing {
|
||||||
return &r.sq
|
return r.sq
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Ring) CQ() *CQRing {
|
func (r *Ring) CQ() CQRing {
|
||||||
return &r.cq
|
return r.cq
|
||||||
}
|
}
|
||||||
|
|
21
core_test.go
21
core_test.go
|
@ -23,10 +23,11 @@ func TestCore(t *testing.T) {
|
||||||
sq := ring.SQ()
|
sq := ring.SQ()
|
||||||
n := 5
|
n := 5
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
sqTail := *sq.Tail()
|
sqTail := *sq.Tail
|
||||||
sqIdx := sqTail & *sq.RingMask()
|
sqIdx := sqTail & *sq.RingMask
|
||||||
|
|
||||||
sqe := sq.Get(sqIdx)
|
sqe := &sq.Event[sqIdx]
|
||||||
|
sqe.Reset()
|
||||||
|
|
||||||
m := mkdata(i)
|
m := mkdata(i)
|
||||||
|
|
||||||
|
@ -37,8 +38,8 @@ func TestCore(t *testing.T) {
|
||||||
sqe.SetOffset(0)
|
sqe.SetOffset(0)
|
||||||
sqe.SetAddr(&m[0])
|
sqe.SetAddr(&m[0])
|
||||||
|
|
||||||
*sq.Array().Get(sqIdx) = *sq.Head() & *sq.RingMask()
|
*sq.Array.Get(sqIdx) = *sq.Head & *sq.RingMask
|
||||||
*sq.Tail()++
|
*sq.Tail++
|
||||||
|
|
||||||
done, err := ring.Enter(1, 1, IORING_ENTER_GETEVENTS, nil)
|
done, err := ring.Enter(1, 1, IORING_ENTER_GETEVENTS, nil)
|
||||||
assert.NoError(t, err, "ring enter")
|
assert.NoError(t, err, "ring enter")
|
||||||
|
@ -47,13 +48,13 @@ func TestCore(t *testing.T) {
|
||||||
|
|
||||||
// get cq
|
// get cq
|
||||||
cq := ring.CQ()
|
cq := ring.CQ()
|
||||||
for i := 0; i < int(*cq.Tail()); i++ {
|
for i := 0; i < int(*cq.Tail); i++ {
|
||||||
cqHead := *cq.Head()
|
cqHead := *cq.Head
|
||||||
cqIdx := cqHead & *cq.RingMask()
|
cqIdx := cqHead & *cq.RingMask
|
||||||
|
|
||||||
cqe := cq.Get(cqIdx)
|
cqe := cq.Event[cqIdx]
|
||||||
|
|
||||||
*cq.Head()++
|
*cq.Head++
|
||||||
t.Logf("CQE %+#v", cqe)
|
t.Logf("CQE %+#v", cqe)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
46
mem_util.go
46
mem_util.go
|
@ -1,6 +1,8 @@
|
||||||
package gouring
|
package gouring
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
@ -68,15 +70,14 @@ func setup(r *Ring, entries uint, parmas *IOUringParams) (ringFd int, err error)
|
||||||
r.sqRingPtr = sqRingPtr
|
r.sqRingPtr = sqRingPtr
|
||||||
r.cqRingPtr = cqRingPtr
|
r.cqRingPtr = cqRingPtr
|
||||||
|
|
||||||
//
|
// SQ
|
||||||
|
|
||||||
// address Go's ring with base+offset allocated
|
sq.Head = (*uint32)(unsafe.Pointer(sqRingPtr + uintptr(p.SQOff.Head)))
|
||||||
sq.head = sqRingPtr + uintptr(p.SQOff.Head)
|
sq.Tail = (*uint32)(unsafe.Pointer(sqRingPtr + uintptr(p.SQOff.Tail)))
|
||||||
sq.tail = sqRingPtr + uintptr(p.SQOff.Tail)
|
sq.RingMask = (*uint32)(unsafe.Pointer(sqRingPtr + uintptr(p.SQOff.RingMask)))
|
||||||
sq.ringMask = sqRingPtr + uintptr(p.SQOff.RingMask)
|
sq.RingEntries = (*uint32)(unsafe.Pointer(sqRingPtr + uintptr(p.SQOff.RingEntries)))
|
||||||
sq.ringEntries = sqRingPtr + uintptr(p.SQOff.RingEntries)
|
sq.Flags = (*uint32)(unsafe.Pointer(sqRingPtr + uintptr(p.SQOff.Flags)))
|
||||||
sq.flags = sqRingPtr + uintptr(p.SQOff.Flags)
|
sq.Array = uint32Array(sqRingPtr + uintptr(p.SQOff.Array)) // non fixed array size, controlled by ring mask
|
||||||
sq.array = uint32Array(sqRingPtr + uintptr(p.SQOff.Array))
|
|
||||||
r.sqesPtr, err = mmap(0, uintptr(p.SQEntries*uint32(_sz_sqe)),
|
r.sqesPtr, err = mmap(0, uintptr(p.SQEntries*uint32(_sz_sqe)),
|
||||||
syscall.PROT_READ|syscall.PROT_WRITE,
|
syscall.PROT_READ|syscall.PROT_WRITE,
|
||||||
syscall.MAP_SHARED|syscall.MAP_POPULATE,
|
syscall.MAP_SHARED|syscall.MAP_POPULATE,
|
||||||
|
@ -85,15 +86,30 @@ func setup(r *Ring, entries uint, parmas *IOUringParams) (ringFd int, err error)
|
||||||
err = errors.Wrap(err, "mmap sqes")
|
err = errors.Wrap(err, "mmap sqes")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
sq.sqes = sqeArray(r.sqesPtr)
|
|
||||||
|
|
||||||
//
|
sq.Event = *(*[]SQEntry)(unsafe.Pointer(&reflect.SliceHeader{
|
||||||
|
Data: r.sqesPtr,
|
||||||
|
Len: int(p.SQEntries),
|
||||||
|
Cap: int(p.SQEntries),
|
||||||
|
}))
|
||||||
|
|
||||||
cq.head = cqRingPtr + uintptr(p.CQOff.Head)
|
fmt.Printf("insp %+#v %+#v\n", len(sq.Event), cap(sq.Event))
|
||||||
cq.tail = cqRingPtr + uintptr(p.CQOff.Tail)
|
|
||||||
cq.ringMask = cqRingPtr + uintptr(p.CQOff.RingMask)
|
// CQ
|
||||||
cq.ringEntries = cqRingPtr + uintptr(p.CQOff.RingEntries)
|
|
||||||
cq.cqes = cqeArray(cqRingPtr + uintptr(p.CQOff.CQEs))
|
cq.Head = (*uint32)(unsafe.Pointer(cqRingPtr + uintptr(p.CQOff.Head)))
|
||||||
|
cq.Tail = (*uint32)(unsafe.Pointer(cqRingPtr + uintptr(p.CQOff.Tail)))
|
||||||
|
cq.RingMask = (*uint32)(unsafe.Pointer(cqRingPtr + uintptr(p.CQOff.RingMask)))
|
||||||
|
cq.RingEntries = (*uint32)(unsafe.Pointer(cqRingPtr + uintptr(p.CQOff.RingEntries)))
|
||||||
|
cqesPtr := cqRingPtr + uintptr(p.CQOff.CQEs)
|
||||||
|
|
||||||
|
cq.Event = *(*[]CQEntry)(unsafe.Pointer(&reflect.SliceHeader{
|
||||||
|
Data: cqesPtr,
|
||||||
|
Len: int(p.CQEntries),
|
||||||
|
Cap: int(p.CQEntries),
|
||||||
|
}))
|
||||||
|
|
||||||
|
fmt.Printf("insp %+#v %+#v\n", len(cq.Event), cap(cq.Event))
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
100
ring.go
100
ring.go
|
@ -20,48 +20,20 @@ type Ring struct {
|
||||||
//-- SQ
|
//-- SQ
|
||||||
|
|
||||||
type SQRing struct {
|
type SQRing struct {
|
||||||
head uintptr
|
Head *uint32
|
||||||
tail uintptr
|
Tail *uint32
|
||||||
ringMask uintptr
|
RingMask *uint32
|
||||||
ringEntries uintptr
|
RingEntries *uint32
|
||||||
flags uintptr
|
Flags *uint32
|
||||||
array uint32Array
|
Array uint32Array
|
||||||
sqes sqeArray
|
Event []SQEntry
|
||||||
}
|
|
||||||
|
|
||||||
func (sq SQRing) Get(idx uint32) *SQEntry {
|
|
||||||
if uintptr(idx) >= uintptr(*sq.RingEntries()) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return sq.sqes.Get(uintptr(idx))
|
|
||||||
}
|
|
||||||
func (sq SQRing) Head() *uint32 {
|
|
||||||
return (*uint32)(unsafe.Pointer(sq.head))
|
|
||||||
}
|
|
||||||
func (sq SQRing) Tail() *uint32 {
|
|
||||||
return (*uint32)(unsafe.Pointer(sq.tail))
|
|
||||||
}
|
|
||||||
func (sq SQRing) RingMask() *uint32 {
|
|
||||||
return (*uint32)(unsafe.Pointer(sq.ringMask))
|
|
||||||
}
|
|
||||||
func (sq SQRing) RingEntries() *uint32 {
|
|
||||||
return (*uint32)(unsafe.Pointer(sq.ringEntries))
|
|
||||||
}
|
|
||||||
func (sq SQRing) Flags() *uint32 {
|
|
||||||
return (*uint32)(unsafe.Pointer(sq.flags))
|
|
||||||
}
|
|
||||||
func (sq SQRing) Array() uint32Array {
|
|
||||||
return sq.array
|
|
||||||
}
|
|
||||||
func (sq SQRing) Event() sqeArray {
|
|
||||||
return sq.sqes
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sq SQRing) IsCQOverflow() bool {
|
func (sq SQRing) IsCQOverflow() bool {
|
||||||
return atomic.LoadUint32(sq.Flags())&IORING_SQ_CQ_OVERFLOW > 0
|
return atomic.LoadUint32(sq.Flags)&IORING_SQ_CQ_OVERFLOW > 0
|
||||||
}
|
}
|
||||||
func (sq SQRing) IsNeedWakeup() bool {
|
func (sq SQRing) IsNeedWakeup() bool {
|
||||||
return atomic.LoadUint32(sq.Flags())&IORING_SQ_NEED_WAKEUP > 0
|
return atomic.LoadUint32(sq.Flags)&IORING_SQ_NEED_WAKEUP > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -75,57 +47,13 @@ func (a uint32Array) Set(idx uint32, v uint32) {
|
||||||
atomic.StoreUint32(a.Get(idx), v)
|
atomic.StoreUint32(a.Get(idx), v)
|
||||||
}
|
}
|
||||||
|
|
||||||
type sqeArray uintptr
|
|
||||||
|
|
||||||
func (sa sqeArray) Get(idx uintptr) *SQEntry {
|
|
||||||
return (*SQEntry)(unsafe.Pointer(uintptr(sa) + idx*_sz_sqe))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sa sqeArray) Set(idx uintptr, v SQEntry) {
|
|
||||||
*sa.Get(idx) = v
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
//-- CQ
|
//-- CQ
|
||||||
|
|
||||||
type CQRing struct {
|
type CQRing struct {
|
||||||
head uintptr
|
Head *uint32
|
||||||
tail uintptr
|
Tail *uint32
|
||||||
ringMask uintptr
|
RingMask *uint32
|
||||||
ringEntries uintptr
|
RingEntries *uint32
|
||||||
cqes cqeArray
|
Event []CQEntry
|
||||||
}
|
|
||||||
|
|
||||||
func (cq CQRing) Get(idx uint32) *CQEntry {
|
|
||||||
if uintptr(idx) >= uintptr(*cq.RingEntries()) { // avoid lookup overflow
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return cq.cqes.Get(uintptr(idx))
|
|
||||||
}
|
|
||||||
func (cq CQRing) Head() *uint32 {
|
|
||||||
return (*uint32)(unsafe.Pointer(cq.head))
|
|
||||||
}
|
|
||||||
func (cq CQRing) Tail() *uint32 {
|
|
||||||
return (*uint32)(unsafe.Pointer(cq.tail))
|
|
||||||
}
|
|
||||||
func (cq CQRing) RingMask() *uint32 {
|
|
||||||
return (*uint32)(unsafe.Pointer(cq.ringMask))
|
|
||||||
}
|
|
||||||
func (cq CQRing) RingEntries() *uint32 {
|
|
||||||
return (*uint32)(unsafe.Pointer(cq.ringEntries))
|
|
||||||
}
|
|
||||||
func (cq CQRing) Event() cqeArray {
|
|
||||||
return cq.cqes
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
type cqeArray uintptr
|
|
||||||
|
|
||||||
func (ca cqeArray) Get(idx uintptr) *CQEntry {
|
|
||||||
return (*CQEntry)(unsafe.Pointer(uintptr(ca) + idx*_sz_cqe))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ca cqeArray) Set(idx uintptr, v CQEntry) {
|
|
||||||
*ca.Get(idx) = v
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue