Coverage report: /home/ellis/comp/core/ffi/uring/pkg.lisp
Kind | Covered | All | % |
expression | 1 | 35 | 2.9 |
branch | 0 | 0 | nil |
Key
Not instrumented
Conditionalized out
Executed
Not executed
Both branches taken
One branch taken
Neither branch taken
1
;;; uring/pkg.lisp --- URING Systems
3
;; /usr/include/liburing.h
7
;; IO_URING is our preferred means of IO on Linux. The bindings here
8
;; are used by the high-level library IO.
10
;; As a point of reference, we look to the SB-SYS:SERVE-EVENT function
11
;; in SBCL. This is an async event loop which dispatches to a backend
12
;; based on features. On Linux it will use either poll or select(2),
13
;; neither of which are particularly fast.
15
;; Using the bindings provided by this library we will implement an
16
;; alternative backend to dispatch to.
18
;; ref: https://kernel.dk/io_uring.pdf
20
;; guide: https://unixism.net/loti/low_level.html
22
;; tokio/io-uring: https://github.com/tokio-rs/io-uring
26
There are two fundamental operations associated with an async
27
interface: the act of submitting a request, and the event that is
28
associated with the completion of said request.
30
For submitting IO, the application is the producer and the kernel is
31
the consumer. The opposite is true for completions - here the kernel
32
produces completion events and the application consumes them.
34
Hence, we need a pair of rings to provide an effective communication
35
channel between an application and the kernel. That pair of rings is
36
at the core of the new interface, io_uring.
38
They are suitably named submission queue (SQ), and completion
39
queue (CQ), and form the foundation of the new interface.
44
(:use :cl :std :sb-alien)
45
(:import-from :sb-posix :file-descriptor :sap-or-nil)
46
(:shadow :build :build-from)
47
(:export :load-uring :io-uring-cq :io-uring-cq*
48
:completion-queue-offsets :completion-queue
49
:completion-queue-entry :completion-queue-entry-32
50
:io-uring-sq :io-uring-sq* :submission-queue-offsets :submission-queue
51
:io-uring-cqe :io-uring-cqe* :io-uring-sqe :io-uring-sqe*
52
:submission-queue-entry :submission-queue-entry-128
53
:io-memory-map :parse-io-uring-params :io-params :io-uring
54
:uring :*default-io-params* :uring-builder :setup-uring-queue
55
:make-uring-queue :build-submitter :sigset-t :cpu-set-t
56
:cpu-mask-t :recv-msg-out :cancel-builder :mmapped-region
57
:with-io-uring :with-new-io-uring :io-uring-get-sqe :io-uring-sqe-set-flags
58
:with-io-sqe :with-new-io-sqe :with-io-cqe :with-new-io-cqe
59
:io-uring-prep-rw :io-uring* :make-io-restriction :io-restriction
60
:io-restriction-p :*default-io-params* :*default-io-entry-count* :io-submitter
64
(define-alien-loader uring "/usr/lib/")
66
(defconstant +cpu-setsize+ 16)
67
(defconstant +sigset-nwords+ 16)
68
(defconstant +ncpu-bits+ 16)
70
(define-alien-type kernel-rwf-t int)
72
(define-alien-type io-uring-op unsigned-int)
74
(define-alien-type io-uring-restriction-slot2
75
(union io-uring-restriction-slot2
76
(register-op unsigned-char)
77
(sqe-op unsigned-char)
78
(sqe-flags unsigned-char)))
80
(define-alien-type io-uring-restriction
81
(struct io-uring-restriction
82
(opcode unsigned-short)
83
(op-or-flags (union io-uring-restriction-slot2))
85
(resv2 (array unsigned-int 3))))
87
(define-alien-type io-uring-buf-ring-resv-and-tail
88
(struct io-uring-buf-ring-resv-and-tail
91
(resv3 unsigned-short)
92
(tail unsigned-short)))
94
(define-alien-type io-uring-buf-ring-slot1
95
(union io-uring-buf-ring-slot1
96
(resv-and-tail io-uring-buf-ring-resv-and-tail)
97
(bufs (* (struct io-uring-buf)))))
99
(define-alien-type io-uring-buf-ring
100
(struct io-uring-buf-ring
101
(tail-or-bufs (union io-uring-buf-ring-slot1))))
103
(define-alien-type io-uring-sqe-cmd-op-and-pad
104
(struct io-uring-sqe-cmd-op-and-pad
105
(cmd-op unsigned-int)
108
(define-alien-type io-uring-sqe-slot5
109
(union io-uring-sqe-slot5
111
(addr2 unsigned-long)
112
(cmd-op-and-pad (struct io-uring-sqe-cmd-op-and-pad))))
114
(define-alien-type io-uring-sqe-slot6
115
(union io-uring-sqe-slot6
117
(splice-off-in unsigned-long)))
119
(define-alien-type io-uring-sqe-slot8
120
(union io-uring-sqe-slot8
121
(rw-flags kernel-rwf-t)
122
(fsync-flags unsigned-int)
123
(poll-events unsigned-short)
124
(poll32-events unsigned-int)
125
(sync-range-flags unsigned-int)
126
(msg-flags unsigned-int)
127
(timeout-flags unsigned-int)
128
(accept-flags unsigned-int)
129
(cancel-flags unsigned-int)
130
(open-flags unsigned-int)
131
(statx-flags unsigned-int)
132
(fadvise-advice unsigned-int)
133
(splice-flags unsigned-int)
134
(rename-flags unsigned-int)
135
(unlink-flags unsigned-int)
136
(hardlink-flags unsigned-int)
137
(xattr-flags unsigned-int)
138
(msg-ring-flags unsigned-int)
139
(uring-cmd-flags unsigned-int)))
141
(define-alien-type io-uring-sqe-slot10
142
(union io-uring-sqe-slot10
143
(buf-index unsigned-short)
144
(buf-group unsigned-short)))
146
(define-alien-type io-uring-sqe-addr-len-and-pad
147
(struct io-uring-sqe-addr-len-and-pad
148
(addr-len unsigned-short)
149
(pad3 (array unsigned-short 1))))
151
(define-alien-type io-uring-sqe-slot12
152
(union io-uring-sqe-slot12
154
(file-index unsigned-int)
155
(addr-len-and-pad (struct io-uring-sqe-addr-len-and-pad))))
157
(define-alien-type io-uring-sqe-addr3-and-pad
158
(struct io-uring-sqe-addr3-and-pad
159
(addr3 unsigned-long)
160
(pad2 (array unsigned-long 1))))
162
(define-alien-type io-uring-sqe-slot13
163
(union io-uring-sqe-slot13
164
(addr3-and-pad (struct io-uring-sqe-addr3-and-pad))
165
(cmd (array unsigned-char 0))))
167
(define-alien-type io-uring-sqe
169
(opcode unsigned-char)
170
(flags unsigned-char)
171
(ioprio unsigned-short)
173
(off-addr-cmd (union io-uring-sqe-slot5))
174
(addr-or-splice-off-in (union io-uring-sqe-slot6))
176
(flags2 (union io-uring-sqe-slot8))
177
(user-data unsigned-long)
178
(buf-opt (union io-uring-sqe-slot10))
179
(personality unsigned-short)
180
(splice-index-addr (union io-uring-sqe-slot12))
181
(addr-or-cmd (union io-uring-sqe-slot13))))
183
(define-alien-type io-uring-sqe* (* (struct io-uring-sqe)))
184
(define-alien-type io-uring-cqe* (* (struct io-uring-cqe)))
186
;; NOTE 2024-05-12: alpha and mips use 535,536,537
187
(defconstant +nr-io-uring-setup+ 425)
188
(defconstant +nr-io-uring-enter+ 426)
189
(defconstant +nr-io-uring-register+ 427)
191
(define-alien-type io-uring-sq
195
(kring-mask (* unsigned))
196
(kring-entries (* unsigned))
197
(kflags (* unsigned))
198
(kdropped (* unsigned))
200
(sqes (* (struct io-uring-sqe)))
203
(ring-sz sb-unix:size-t)
206
(ring-entries unsigned)
207
(pad (array unsigned 2))))
209
(define-alien-type io-uring-sq* (* (struct io-uring-sq)))
211
(define-alien-type io-uring-cq
215
(kring-mask (* unsigned))
216
(kring-entries (* unsigned))
217
(kflags (* unsigned))
218
(koverflow (* unsigned))
219
(cqes (* (struct io-uring-cqe)))
220
(ring-sz sb-unix:size-t)
223
(ring-entries unsigned)
224
(pad (array unsigned-int 2))))
226
(define-alien-type io-uring-cq* (* (struct io-uring-cq)))
228
(define-alien-type io-uring
230
(sq (struct io-uring-sq))
231
(cq (struct io-uring-cq))
236
(int-flags unsigned-char)
237
(pad (array unsigned-char 3))
240
(define-alien-type io-uring* (* io-uring))
242
(define-alien-type io-uring-probe* (* (struct io-uring-probe)))