add capability check

This commit is contained in:
kadmin
2021-07-07 18:15:52 +00:00
parent 9fd01334cf
commit 1f9021e287
4 changed files with 72 additions and 5 deletions

View File

@@ -21,3 +21,42 @@ func Available() bool {
// DisabledError indicates that io_uring was explicitly disabled.
var DisabledError = errors.New("io_uring disabled")
type IORingOp = int
//https://unixism.net/loti/tutorial/probe_liburing.html
const (
IORING_OP_NOP IORingOp = iota
IORING_OP_READV
IORING_OP_WRITEV
IORING_OP_FSYNC
IORING_OP_READ_FIXED
IORING_OP_WRITE_FIXED
IORING_OP_POLL_ADD
IORING_OP_POLL_REMOVE
IORING_OP_SYNC_FILE_RANGE
IORING_OP_SENDMSG
IORING_OP_RECVMSG
IORING_OP_TIMEOUT
IORING_OP_TIMEOUT_REMOVE
IORING_OP_ACCEPT
IORING_OP_ASYNC_CANCEL
IORING_OP_LINK_TIMEOUT
IORING_OP_CONNECT
IORING_OP_FALLOCATE
IORING_OP_OPENAT
IORING_OP_CLOSE
IORING_OP_FILES_UPDATE
IORING_OP_STATX
IORING_OP_READ
IORING_OP_WRITE
IORING_OP_FADVISE
IORING_OP_MADVISE
IORING_OP_SEND
IORING_OP_RECV
IORING_OP_OPENAT2
IORING_OP_EPOLL_CTL
IORING_OP_SPLICE
IORING_OP_PROVIDE_BUFFERS
IORING_OP_REMOVE_BUFFERS
)

View File

@@ -182,6 +182,15 @@ static int set_deadline(struct io_uring *ring, int64_t sec, long long ns) {
return 0;
}
// index of io uring capability
static int has_capability(int i) {
int supported;
struct io_uring_probe *probe = io_uring_get_probe();
supported = io_uring_opcode_supported(probe, i);
free(probe);
return supported;
}
#endif
static int has_io_uring(void) {

View File

@@ -71,6 +71,24 @@ type UDPConn struct {
reads int32
}
var (
mu sync.Mutex
// checks capabilities available on this system
capabilities map[IORingOp]bool
)
func checkCapability(op IORingOp) bool {
mu.Lock()
defer mu.Unlock()
if v, ok := capabilities[op]; ok {
return v
}
has_op := C.has_capability(C.int(op)) == 1
capabilities[op] = has_op
return has_op
}
func NewUDPConn(pconn net.PacketConn) (*UDPConn, error) {
if !*useIOURing {
return nil, DisabledError

View File

@@ -52,10 +52,10 @@ func TestUDPSendRecv(t *testing.T) {
Port: TestPort,
}
func NewUDPTestServer(t *testing.T) error {
func NewUDPTestServer(t *testing.T) (closer func() error, err error) {
conn, err := net.ListenUDP("udp", serverAddr)
if err != nil {
return err
return nil, err
}
go func() {
for {
@@ -67,7 +67,7 @@ func NewUDPTestServer(t *testing.T) error {
}
}
}()
return nil
return conn.Close, nil
}
func TestUDPConn(t *testing.T) {
@@ -76,8 +76,9 @@ func TestUDPConn(t *testing.T) {
}
c := qt.New(t)
// TODO add a closer here
err := NewUDPTestServer(t)
closer, err := NewUDPTestServer(t)
c.Assert(err, qt.IsNil)
t.Cleanup(func() { closer() })
udpConn, err := net.DialUDP("udp", nil, serverAddr)
c.Assert(err, qt.IsNil)
defer udpConn.Close()
@@ -94,7 +95,7 @@ func TestUDPConn(t *testing.T) {
}
// Test many writes at once
for i := 0; i < 1000; i++ {
for i := 0; i < 256; i++ {
n, err := conn.WriteTo(content, serverAddr)
c.Assert(err, qt.IsNil)
if n != len(content) {