1.1--- a/lisp/ffi/uring/constants.lisp Tue Mar 26 22:30:19 2024 -0400
1.2+++ b/lisp/ffi/uring/constants.lisp Wed Mar 27 21:45:07 2024 -0400
1.3@@ -3,18 +3,17 @@
1.4 "linux/fs.h" "liburing/io_uring_version.h" "liburing/barrier.h"
1.5 "linux/types.h" "liburing/io_uring.h")
1.6
1.7-(
1.8- ;; sys/uio.h
1.9+( ;; sys/uio.h
1.10 (:structure iovec ("struct iovec"
1.11 (unsigned-long iov-base "ptr_t" "iov_base")
1.12 (sb-unix:size-t iov-len "size_t" "iov_len")))
1.13- ;; sys/socet.h
1.14+ ;; bits/socket.h
1.15 (:structure msghdr ("struct msghdr"
1.16- (int msg-name "void" "msg_name") ;; *
1.17+ ((* t) msg-name "void *" "msg_name")
1.18 (unsigned-int msg-namelen "socklen_t" "msg_namelen")
1.19- (int msg-iov "struct iovec" "msg_iov") ;; *
1.20+ ((* iovec) msg-iov "struct iovec *" "msg_iov")
1.21 (sb-unix:size-t msg-iovlen "size_t" "msg_iovlen")
1.22- (int msg-control "void" "msg_control") ;; *
1.23+ ((* t) msg-control "void *" "msg_control")
1.24 (sb-unix:size-t msg-controllen "size_t" "msg_controllen")
1.25 (int msg-flags "int" "msg_flags")))
1.26 ;; linux/time.h
2.1--- a/lisp/ffi/uring/cq.lisp Tue Mar 26 22:30:19 2024 -0400
2.2+++ b/lisp/ffi/uring/cq.lisp Wed Mar 27 21:45:07 2024 -0400
2.3@@ -23,6 +23,17 @@
2.4
2.5 (define-alien-type io-uring-cq* (* (struct io-uring-cq)))
2.6
2.7+(defstruct completion-queue-offsets
2.8+ (head 0 :type fixnum)
2.9+ (tail 0 :type fixnum)
2.10+ (ring-mask 0 :type fixnum)
2.11+ (ring-entries 0 :type fixnum)
2.12+ (overflow 0 :type fixnum)
2.13+ (cqes 0 :type fixnum)
2.14+ (flags 0 :type fixnum)
2.15+ ;; resv1
2.16+ (user-addr 0 :type fixnum))
2.17+
2.18 (defstruct completion-queue
2.19 (head 0 :type fixnum)
2.20 (tail 0 :type fixnum)
3.1--- a/lisp/ffi/uring/pkg.lisp Tue Mar 26 22:30:19 2024 -0400
3.2+++ b/lisp/ffi/uring/pkg.lisp Wed Mar 27 21:45:07 2024 -0400
3.3@@ -39,12 +39,12 @@
3.4 |#
3.5 ;;; Code:
3.6 (defpackage :uring
3.7- (:use :cl :std :sb-alien)
3.8+ (:use :cl :std :sb-alien :dat/proto)
3.9 (:export :load-uring))
3.10
3.11 (in-package :uring)
3.12 (define-alien-loader "uring" t "/usr/lib/")
3.13-
3.14+(load-uring)
3.15 ;;; barrier.h
3.16 ;; (defun io-uring-write-once (var val))
3.17 ;; (defun io-uring-read-once (var))
3.18@@ -56,76 +56,6 @@
3.19 (defmacro defalien-int (name &rest args)
3.20 `(define-alien-routine ,name int ,@args))
3.21
3.22-(define-alien-type nil
3.23- (struct io-uring
3.24- (sq (struct io-uring-sq))
3.25- (cq (struct io-uring-cq))
3.26- (flags unsigned-int)
3.27- (ring-fd int)
3.28- (features unsigned-int)
3.29- (enter-ring-fd int)
3.30- (int-flags char)
3.31- (pad (array char 3))
3.32- (pad2 unsigned-int)))
3.33-
3.34-(define-alien-routine io-uring-get-probe-ring (* io-uring-probe) (ring (* (struct io-uring))))
3.35-(define-alien-routine io-uring-get-probe (* io-uring-probe))
3.36-(define-alien-routine io-uring-free-probe void (* io-uring-probe))
3.37-;;...
3.38-
3.39-(defalien-int io-uring-queue-init (entries int) (ring (* (struct io-uring))) (flags unsigned))
3.40-
3.41-
3.42-;;...
3.43-
3.44-(defalien-int io-uring-submit (ring (* (struct io-uring))))
3.45-
3.46-(defalien-int io-uring-register
3.47- (fd int)
3.48- (opcode unsigned-int)
3.49- (args (* t))
3.50- (nr-args unsigned-int))
3.51-
3.52-;;...
3.53-(defalien-int io-uring-register-buffers
3.54- (ring (* (struct io-uring)))
3.55- (iovecs (* (struct iovec)))
3.56- (nr-iovecs unsigned-int))
3.57-
3.58-;;...
3.59-
3.60-(defalien-int io-uring-enable-rings (ring (* (struct io-uring))))
3.61-(defalien-int io-uring-sqring-wait (ring (* (struct io-uring))))
3.62-
3.63-;;...
3.64-(defalien-int io-uring-setup
3.65- (entries unsigned-int)
3.66- (p (* (struct io-uring-params))))
3.67-
3.68-(defalien-int io-uring-enter
3.69- (fd int)
3.70- (to-submit unsigned-int)
3.71- (min-complete unsigned-int)
3.72- (flags unsigned-int)
3.73- (arg (* t))
3.74- (size unsigned-long))
3.75-
3.76-(define-alien-routine io-uring-setup-buf-ring (* (struct io-uring-buf-ring))
3.77- (ring (* (struct io-uring)))
3.78- (nentries unsigned-int)
3.79- (bgid int)
3.80- (flags unsigned-int)
3.81- (ret (* int)))
3.82-(defalien-int io-uring-free-buf-ring
3.83- (ring (* (struct io-uring)))
3.84- (br (* (struct io-uring-buf-ring)))
3.85- (nentries unsigned-int)
3.86- (bgid int))
3.87-;;...
3.88-
3.89-;; peek-cqe wait-cqe get-sqe
3.90-;; io-uring-buf-ring-init
3.91-
3.92 (defalien-int io-uring-major-version)
3.93 (defalien-int io-uring-minor-version)
3.94 (defalien-int io-uring-check-version (major int) (minor int))
4.1--- a/lisp/ffi/uring/sq.lisp Tue Mar 26 22:30:19 2024 -0400
4.2+++ b/lisp/ffi/uring/sq.lisp Wed Mar 27 21:45:07 2024 -0400
4.3@@ -25,6 +25,17 @@
4.4
4.5 (define-alien-type io-uring-sq* (* (struct io-uring-sq)))
4.6
4.7+(defstruct submission-queue-offsets
4.8+ (head 0 :type fixnum)
4.9+ (tail 0 :type fixnum)
4.10+ (ring-mask 0 :type fixnum)
4.11+ (ring-entries 0 :type fixnum)
4.12+ (flags 0 :type fixnum)
4.13+ (dropped 0 :type fixnum)
4.14+ (array 0 :type fixnum)
4.15+ ;; resv1
4.16+ (user-addr 0 :type fixnum))
4.17+
4.18 ;; used to send IO requests to the kernel
4.19 (defstruct submission-queue
4.20 (head 0 :type fixnum)
5.1--- a/lisp/ffi/uring/uring.asd Tue Mar 26 22:30:19 2024 -0400
5.2+++ b/lisp/ffi/uring/uring.asd Wed Mar 27 21:45:07 2024 -0400
5.3@@ -8,7 +8,8 @@
5.4 (in-package :uring.sys)
5.5
5.6 (defsystem :uring
5.7- :depends-on (:sb-grovel :std)
5.8+ :depends-on (:sb-grovel :std :dat)
5.9+ :serial t
5.10 :components ((:file "pkg")
5.11 (grovel-constants-file "constants"
5.12 :package :uring)
6.1--- a/lisp/ffi/uring/uring.lisp Tue Mar 26 22:30:19 2024 -0400
6.2+++ b/lisp/ffi/uring/uring.lisp Wed Mar 27 21:45:07 2024 -0400
6.3@@ -14,19 +14,154 @@
6.4 (sqe-mmap nil :type mmapped-region)
6.5 (cq-mmap nil :type mmapped-region))
6.6
6.7-(defstruct io-parameters (params nil :type io-uring-params))
6.8+(defun parse-io-uring-params (params)
6.9+ "Parse IO-URING-PARAMS foreign struct, return an IO-PARAMS struct."
6.10+ (let ((res 0))
6.11+ (loop while params
6.12+ do (1+ res))
6.13+ res))
6.14+
6.15+(defstruct io-params
6.16+ (sq-entries 0 :type fixnum)
6.17+ (cq-entries 0 :type fixnum)
6.18+ (flags 0 :type fixnum)
6.19+ (sq-thread-cpu 0 :type fixnum)
6.20+ (sq-thread-idle 0 :type fixnum)
6.21+ (features 0 :type fixnum)
6.22+ (wq-fd 0 :type fixnum)
6.23+ ;; resv
6.24+ (sq-off (make-submission-queue-offsets) :type submission-queue-offsets) ;; offsets are 40bytes each
6.25+ (cq-off (make-completion-queue-offsets) :type completion-queue-offsets))
6.26+
6.27+(defmacro define-io-param-flag (name const)
6.28+ "Create a predicate method with NAME which checks for presence of flag
6.29+CONST in FLAGS slot of IO-PARAMS. A SETF expansion is also defined
6.30+which accepts a boolean value and automatically adjusts the slot.")
6.31+
6.32+(defmacro define-io-param-feature (name const)
6.33+ "Create a predicate method with NAME which checks for presence of flag
6.34+CONST in FEATURES slot of IO-PARAMS. A SETF expansion is also defined
6.35+which accepts a boolean value and automatically adjust the slot.")
6.36+
6.37+;; (define-io-param-flag setup-sqpoll-p ioring-setup-sqpoll)
6.38+;; (define-io-param-flag setup-iopoll-p ioring-setup-iopoll)
6.39+;; (define-io-param-flag setup-single-issuer-p ioring-setup-single-issuer)
6.40+;; (define-io-param-flag setup-iopoll-p ioring-setup-iopoll)
6.41+;; (define-io-param-feature feat-single-mmap-p ioring-feat-single-mmap)
6.42+;; (define-io-param-feature feat-nodrop-p ioring-feat-nodrop)
6.43+;; (define-io-param-feature feat-submit-stable-p ioring-feat-submit-stable)
6.44+;; (define-io-param-feature feat-rw-cur-pos-p ioring-feat-rw-cur-pos)
6.45+;; (define-io-param-feature feat-cur-personality-p ioring-feat-cur-personality)
6.46+;; (define-io-param-feature feat-fast-poll-p ioring-feat-fast-poll-p)
6.47+;; (define-io-param-feature feat-poll-32bits-p ioring-feat-poll-32bits-p)
6.48+;; (define-io-param-feature feat-sqpoll-nonfixed-p ioring-feat-sqpoll-nonfixed)
6.49+;; (define-io-param-feature feat-ext-arg-p ioring-feat-ext-arg)
6.50+;; (define-io-param-feature feat-native-workers-p ioring-feat-native-workers)
6.51+;; (define-io-param-feature feat-rsrc-tags-p ioring-feat-rsrc-tags)
6.52+;; (define-io-param-feature feat-cqe-skip-p ioring-feat-cqe-skip)
6.53+;; (define-io-param-feature feat-linked-file-p ioring-feat-linked-file)
6.54+
6.55+(defmethod build ((self io-params) &key &allow-other-keys)
6.56+ (with-slots (sq-entries cq-entries flags sq-thread-cpu sq-thread-idle features wq-fd sq-off cq-off) self
6.57+ (with-io-uring-params res ((sq-entries sq-entries) (cq-entries cq-entries) (flags flags)
6.58+ (sq-thread-cpu sq-thread-cpu) (sq-thread-idle sq-thread-idle) (features features)
6.59+ (wq-fd wq-fd) (sq-off sq-off) (cq-off cq-off))
6.60+ res)))
6.61+
6.62+(define-alien-type nil
6.63+ (struct io-uring
6.64+ (sq (struct io-uring-sq))
6.65+ (cq (struct io-uring-cq))
6.66+ (flags unsigned-int)
6.67+ (ring-fd int)
6.68+ (features unsigned-int)
6.69+ (enter-ring-fd int)
6.70+ (int-flags char)
6.71+ (pad (array char 3))
6.72+ (pad2 unsigned-int)))
6.73
6.74 ;; io-uring instance
6.75-(defstruct io-uring
6.76+(defstruct uring
6.77 (sq nil :type submission-queue)
6.78 (cq nil :type completion-queue)
6.79 (fd nil :type sb-posix:file-descriptor) ;; owned fd
6.80- (params nil :type io-parameters) ;; TODO io-params
6.81+ (params nil :type io-params)
6.82 (memory nil :type io-memory-map))
6.83
6.84-(defstruct io-uring-builder
6.85- (dontfork nil :type boolean)
6.86- (params nil :type io-uring-params))
6.87+(defvar *default-io-params* (make-io-params))
6.88+(defstruct uring-builder
6.89+ (params *default-io-params* :type io-params)
6.90+ (dontfork nil :type boolean))
6.91+
6.92+(defmethod build ((self uring-builder) &key (entries 256) &allow-other-keys))
6.93+
6.94+(defun setup-queue (fd p)
6.95+ "Setup a URING struct given a reference to a FILE-DESCRIPTOR and IO-PARAMS.")
6.96+
6.97+(defun make-queue (entries)
6.98+ "Create a new URING instance with default params. N is the size of the
6.99+queue, which must be a power of two."
6.100+ (build (make-uring-builder) :entries entries))
6.101+
6.102+(defmethod build-submitter ((self uring)))
6.103
6.104 ;;; Syscalls
6.105 ;; register, setup, enter
6.106+
6.107+(define-alien-routine io-uring-get-probe-ring (* io-uring-probe) (ring (* (struct io-uring))))
6.108+(define-alien-routine io-uring-get-probe (* io-uring-probe))
6.109+(define-alien-routine io-uring-free-probe void (* io-uring-probe))
6.110+;;...
6.111+
6.112+(defalien-int io-uring-queue-init (entries int) (ring (* (struct io-uring))) (flags unsigned))
6.113+
6.114+
6.115+;;...
6.116+
6.117+(defalien-int io-uring-submit (ring (* (struct io-uring))))
6.118+
6.119+(defalien-int io-uring-register
6.120+ (fd int)
6.121+ (opcode unsigned-int)
6.122+ (args (* t))
6.123+ (nr-args unsigned-int))
6.124+
6.125+;;...
6.126+(defalien-int io-uring-register-buffers
6.127+ (ring (* (struct io-uring)))
6.128+ (iovecs (* (struct iovec)))
6.129+ (nr-iovecs unsigned-int))
6.130+
6.131+;;...
6.132+
6.133+(defalien-int io-uring-enable-rings (ring (* (struct io-uring))))
6.134+(defalien-int io-uring-sqring-wait (ring (* (struct io-uring))))
6.135+
6.136+;;...
6.137+(defalien-int io-uring-setup
6.138+ (entries unsigned-int)
6.139+ (p (* (struct io-uring-params))))
6.140+
6.141+(defalien-int io-uring-enter
6.142+ (fd int)
6.143+ (to-submit unsigned-int)
6.144+ (min-complete unsigned-int)
6.145+ (flags unsigned-int)
6.146+ (arg (* t))
6.147+ (size unsigned-long))
6.148+
6.149+(define-alien-routine io-uring-setup-buf-ring (* (struct io-uring-buf-ring))
6.150+ (ring (* (struct io-uring)))
6.151+ (nentries unsigned-int)
6.152+ (bgid int)
6.153+ (flags unsigned-int)
6.154+ (ret (* int)))
6.155+(defalien-int io-uring-free-buf-ring
6.156+ (ring (* (struct io-uring)))
6.157+ (br (* (struct io-uring-buf-ring)))
6.158+ (nentries unsigned-int)
6.159+ (bgid int))
6.160+;;...
6.161+
6.162+;; peek-cqe wait-cqe get-sqe
6.163+;; io-uring-buf-ring-init
7.1--- a/lisp/lib/io/io.asd Tue Mar 26 22:30:19 2024 -0400
7.2+++ b/lisp/lib/io/io.asd Wed Mar 27 21:45:07 2024 -0400
7.3@@ -1,6 +1,6 @@
7.4 (defsystem :io
7.5- :description "Data formats"
7.6- :depends-on (:cl-ppcre :std :obj :uring)
7.7+ :description "Lisp IO Interface"
7.8+ :depends-on (:cl-ppcre :std :obj :uring :sb-bsd-sockets)
7.9 :version "0.1.0"
7.10 :serial t
7.11 :components ((:file "pkg"))
8.1--- a/lisp/lib/io/pkg.lisp Tue Mar 26 22:30:19 2024 -0400
8.2+++ b/lisp/lib/io/pkg.lisp Wed Mar 27 21:45:07 2024 -0400
8.3@@ -4,6 +4,11 @@
8.4
8.5 ;;; Code:
8.6 (defpackage :io
8.7- (:use :cl :std :obj/id :uring))
8.8+ (:use :cl :std :obj/id :uring :sb-bsd-sockets))
8.9
8.10 (in-package :io)
8.11+
8.12+(defun init-uring (params &optional dontfork)
8.13+ "Initialize an IO-URING structure. If NOFORK is non-nil, advise the
8.14+kernel that the mmapped regions should not be accessible to forked
8.15+processes.")
9.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2+++ b/lisp/lib/io/readme.txt Wed Mar 27 21:45:07 2024 -0400
9.3@@ -0,0 +1,11 @@
9.4+IO library
9.5+
9.6+first-class backend is IO_URING. everything else defers to whatever is
9.7+most portable (on Windows and Mac). The URING system provides low
9.8+level bindings to IO_URING.
9.9+
9.10+We implement a high-level API for IO. The API is meant to be as simple
9.11+as possible, while still providing a great deal of control over the
9.12+primitive IO queues.
9.13+
9.14+Speed is the priority, above all else.
10.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2+++ b/lisp/lib/io/tests.lisp Wed Mar 27 21:45:07 2024 -0400
10.3@@ -0,0 +1,7 @@
10.4+(defpackage :io/tests
10.5+ (:use :cl :std :rt :io))
10.6+(in-package :io/tests)
10.7+(defsuite :io)
10.8+(in-suite :io)
10.9+
10.10+(deftest sanity ())