read-write-fixed.dhover×182all
#!/usr/bin/env dub
/+ dub.sdl:
    name "io_uring_read_write_fixed"
    dependency "during" version="~>0.5.0"
    platforms "linux"
    targetPath "build"
+/
/**
 * `io_uring` — registered (fixed) buffers with `IORING_OP_WRITE_FIXED` /
 * `IORING_OP_READ_FIXED` (Linux 5.1).
 *
 * Fixed buffers shipped in the original 5.1 introduction alongside `NOP` and the
 * vectored read/write ops. The idea: register a fixed set of user buffers with the
 * kernel **once** (`io_uring_register(IORING_REGISTER_BUFFERS)`), so the kernel can
 * pin and map their pages up front. Subsequent `*_FIXED` ops then refer to a buffer
 * by **index** instead of an address+length, letting the kernel skip the per-I/O
 * `get_user_pages` / page-pinning dance — the headline zero-overhead-mapping win.
 *
 * This example:
 *   1. opens a throwaway file under `/tmp` (`O_CREAT|O_RDWR|O_TRUNC`),
 *   2. registers ONE buffer with `io.registerBuffers(buf[])`,
 *   3. `WRITE_FIXED`s a known payload from buffer index 0 at offset 0,
 *   4. clears the buffer region, then `READ_FIXED`s it back into index 0,
 *   5. asserts the bytes round-trip.
 *
 * Companion to the io_uring chronology:
 * see docs/research/async-io/io-uring/timeline.md § "5.1 — The introduction".
 *
 * Run with: `dub run --single read-write-fixed.d`
 *
 * Portability: fixed buffers are part of the 5.1 baseline, so no feature probe is
 * needed — but if the running kernel has no `io_uring` at all (too old, or blocked
 * by a seccomp/container policy), `setup` fails and we print a `SKIP:` line and exit
 * 0 so the example stays green in CI regardless of host kernel.
 */
module 
(module) io_uring_read_write_fixed

io_uring — registered (fixed) buffers with IORING_OP_WRITE_FIXED / IORING_OP_READ_FIXED (Linux 5.1).

Fixed buffers shipped in the original 5.1 introduction alongside NOP and the vectored read/write ops. The idea: register a fixed set of user buffers with the kernel once (io_uring_register(IORING_REGISTER_BUFFERS)), so the kernel can pin and map their pages up front. Subsequent *_FIXED ops then refer to a buffer by index instead of an address+length, letting the kernel skip the per-I/O get_user_pages / page-pinning dance — the headline zero-overhead-mapping win.

This example:

  1. opens a throwaway file under /tmp (O_CREAT|O_RDWR|O_TRUNC),

  2. registers ONE buffer with io.registerBuffers(buf[]),

  3. WRITE_FIXEDs a known payload from buffer index 0 at offset 0,

  4. clears the buffer region, then READ_FIXEDs it back into index 0,

  5. asserts the bytes round-trip.

Companion to the io_uring chronology: see docs/research/async-io/io-uring/timeline.md § "5.1 — The introduction".

Run with: dub run --single read-write-fixed.d

Portability

fixed buffers are part of the 5.1 baseline, so no feature probe is needed — but if the running kernel has no io_uring at all (too old, or blocked by a seccomp/container policy), setup fails and we print a SKIP: line and exit 0 so the example stays green in CI regardless of host kernel.

io_uring_read_write_fixed
;
import
(module) during

Simple idiomatic dlang wrapper around linux io_uring (see: https://kernel.dk/io_uring.pdf) asynchronous API.

during
;
import
(package) std
std
.
(module) std.stdio
Category Symbols
File handles _popen File isFileHandle openNetwork stderr stdin stdout
Reading chunks lines readf readfln readln
Writing toFile write writef writefln writeln
Misc KeepTerminator LockType StdioException

Standard I/O functions that extend core.stdc.stdio. core.stdc.stdio is publically imported when importing std.stdio.

There are three layers of I/O:

  1. The lowest layer is the operating system layer. The two main schemes are Windows and Posix.

  2. C's stdio.h which unifies the two operating system schemes.

  3. std.stdio, this module, unifies the various stdio.h implementations into a high level package for D programs.

Source

std/stdio.d

@copyrightCopyright The D Language Foundation 2007-.@licenseBoost License 1.0.@authorsWalter Bright, Andrei Alexandrescu, Alex Rønne Petersen
stdio
:
(alias template) io_uring_read_write_fixed.writefln = std.stdio.writefln(alias fmt, A...)(A args) if (isSomeString!(typeof(fmt)))

Equivalent to writef(fmt, args, '\n').

writefln
, stderr;
import
(package) core
core
.
(package) core.stdc
stdc
.
(module) core.stdc.stdlib

D header file for C99.

pubs.opengroup.org/onlinepubs/009695399/basedefs/stdlib.h.html, stdlib.h

Source

core/stdc/stdlib.d

@copyrightCopyright Sean Kelly 2005 - 2014.@licenseDistributed under the Boost Software License 1.0. (See accompanying file LICENSE)@authorsSean Kelly@standardsISO/IEC 9899:1999 (E)
stdlib
:
(alias) io_uring_read_write_fixed.free = void core.stdc.stdlib.free(void* ptr) nothrow @nogc
free
,
(alias) io_uring_read_write_fixed.malloc = void* core.stdc.stdlib.malloc(ulong size) nothrow @nogc
malloc
;
import
(package) core
core
.
(package) core.sys
sys
.
(package) core.sys.linux
linux
.
(module) core.sys.linux.errno

D header file for GNU/Linux

glibc stdlib/errno.h

errno
:
(alias constant) io_uring_read_write_fixed.EINVAL = int core.stdc.errno.EINVAL = 22
EINVAL
,
(alias constant) io_uring_read_write_fixed.ENOSYS = int core.stdc.errno.ENOSYS = 38
ENOSYS
,
(alias constant) io_uring_read_write_fixed.EOPNOTSUPP = int core.stdc.errno.EOPNOTSUPP = 95
EOPNOTSUPP
;
import
(package) core
core
.
(package) core.sys
sys
.
(package) core.sys.linux
linux
.
(module) core.sys.linux.fcntl
fcntl
:
(alias constant) io_uring_read_write_fixed.O_CREAT = int core.sys.posix.fcntl.O_CREAT = 64
O_CREAT
,
(alias constant) io_uring_read_write_fixed.O_RDWR = int core.sys.posix.fcntl.O_RDWR = 2
O_RDWR
,
(alias constant) io_uring_read_write_fixed.O_TRUNC = int core.sys.posix.fcntl.O_TRUNC = 512
O_TRUNC
, open;
import
(package) core
core
.
(package) core.sys
sys
.
(package) core.sys.posix
posix
.
(module) core.sys.posix.unistd

D header file for POSIX.

@copyrightCopyright Sean Kelly 2005 - 2009.@licenseBoost License 1.0.@authorsSean Kelly@standardsThe Open Group Base Specifications Issue 8, IEEE Std 1003.1, 2024 Edition
unistd
:
(alias) io_uring_read_write_fixed.close = int core.sys.posix.unistd.close(int) nothrow @nogc @trusted
close
,
(alias) io_uring_read_write_fixed.unlink = int core.sys.posix.unistd.unlink(scope const(char*)) nothrow @nogc
unlink
;
int
int D main()
main
()
{ enum
(alias) object.string = string
string
(constant) string io_uring_read_write_fixed.main.payload = "io_uring fixed buffers, since Linux 5.1"
payload
= "io_uring fixed buffers, since Linux 5.1";
(struct) during.Uring

Main entry point to work with io_uring.

It hides SubmissionQueue and CompletionQueue behind standard range interface. We put in SubmissionEntry entries and take out CompletionEntry entries.

Use predefined prepXX methods to fill required fields of SubmissionEntry before put or during putWith.

Note

prepXX functions doesn't touch previous entry state, just fills in operation properties. This is because for less error prone interface it is cleared automatically when prepared using putWith. So when using on own SubmissionEntry (outside submission queue), that would be added to the submission queue using put, be sure its cleared if it's reused for multiple operations.

Uring
(local variable) during.Uring io
io
;
const
(local variable) const(int) setupRet
setupRet
=
(local variable) during.Uring io
io
.
int during.setup(ref during.Uring uring, uint entries = 128u, during.io_uring.SetupFlags flags = SetupFlags.NONE) nothrow @nogc @safe

Setup new instance of io_uring into provided Uring structure.

@paramuring Uring structure to be initialized (must not be already initialized)@paramentries Number of entries to initialize uring with@paramflags SetupFlags to use to initialize uring.@returnsOn succes it returns 0, -errno otherwise.
setup
(8);
if (
(local variable) const(int) setupRet
setupRet
< 0)
{
void std.stdio.writefln!(char, const(int))(in char[] fmt, const(int) __param_1) @safe

Equivalent to writef(fmt, args, '\n').

writefln
("SKIP: io_uring_setup failed (errno %d) — io_uring unavailable on this host", -
(local variable) const(int) setupRet
setupRet
);
return 0; } // A throwaway file we own; unlinked on exit. The trailing NUL keeps it a valid // C string for the libc open()/unlink() calls. static immutable char[]
(immutable global) immutable(string) io_uring_read_write_fixed.main.path
path
= "/tmp/io_uring_rw_fixed_example.tmp\0";
const
(local variable) const(int) fd
fd
= open(&
(immutable global) immutable(string) io_uring_read_write_fixed.main.path
path
[0],
(constant) int core.sys.posix.fcntl.O_CREAT = 64
O_CREAT
|
(constant) int core.sys.posix.fcntl.O_RDWR = 2
O_RDWR
|
(constant) int core.sys.posix.fcntl.O_TRUNC = 512
O_TRUNC
,
(template instance) io_uring_read_write_fixed.octal!"600"
octal
!"600");
if (
(local variable) const(int) fd
fd
< 0)
{ stderr.
std.stdio.File std.stdio.makeGlobal!"core.stdc.stdio.stderr"() nothrow @nogc @property ref @system
writefln
("open(%s) failed",
(immutable global) immutable(string) io_uring_read_write_fixed.main.path
path
[0 .. $ - 1]);
return 1; } scope (exit) {
int core.sys.posix.unistd.close(int) nothrow @nogc @trusted
close
(
(local variable) const(int) fd
fd
);
int core.sys.posix.unistd.unlink(scope const(char*)) nothrow @nogc
unlink
(&
(immutable global) immutable(string) io_uring_read_write_fixed.main.path
path
[0]);
} // Register a single fixed buffer. `registerBuffers` pins the pages and maps them // into the kernel once; *_FIXED ops below reference this region by index 0. enum
(alias) object.size_t = ulong
size_t
(constant) ulong io_uring_read_write_fixed.main.bufLen = 4096LU
bufLen
= 4096;
auto
(local variable) ubyte* bp
bp
= cast(ubyte*)
void* core.stdc.stdlib.malloc(ulong size) nothrow @nogc
malloc
(
(constant) ulong io_uring_read_write_fixed.main.bufLen = 4096LU
bufLen
);
if (
(local variable) ubyte* bp
bp
is null)
{ stderr.
std.stdio.File std.stdio.makeGlobal!"core.stdc.stdio.stderr"() nothrow @nogc @property ref @system
writefln
("malloc(%d) failed",
(constant) ulong io_uring_read_write_fixed.main.bufLen = 4096LU
bufLen
);
return 1; } scope (exit)
void core.stdc.stdlib.free(void* ptr) nothrow @nogc
free
(
(local variable) ubyte* bp
bp
);
ubyte[]
(local variable) ubyte[] buffer
buffer
=
(local variable) ubyte* bp
bp
[0 ..
(constant) ulong io_uring_read_write_fixed.main.bufLen = 4096LU
bufLen
];
const
(local variable) const(int) regRet
regRet
=
(local variable) during.Uring io
io
.
int during.Uring.registerBuffers!(ubyte[])(ubyte[] buffers) nothrow @nogc @system

Register single buffer to be mapped into the kernel for faster buffered operations.

To use the buffers, the application must specify the fixed variants for of operations, READ_FIXED or WRITE_FIXED in the SubmissionEntry also with used buf_index set in entry extra data.

An application can increase or decrease the size or number of registered buffers by first unregistering the existing buffers, and then issuing a new call to io_uring_register() with the new buffers.

@parambuffer Buffers to be registered@returnsOn success, returns 0. On error, -errno is returned.
registerBuffers
(
(local variable) ubyte[] buffer
buffer
);
if (
(local variable) const(int) regRet
regRet
< 0)
{ // Registration itself is a 5.1 baseline feature; an error here is unexpected. stderr.
std.stdio.File std.stdio.makeGlobal!"core.stdc.stdio.stderr"() nothrow @nogc @property ref @system
writefln
("registerBuffers failed: errno %d", -
(local variable) const(int) regRet
regRet
);
return 1; } scope (exit)
(local variable) during.Uring io
io
.
int during.Uring.unregisterBuffers() nothrow @nogc @trusted

Releases all previously registered buffers associated with the io_uring instance.

An application need not unregister buffers explicitly before shutting down the io_uring instance.

@returnsOn success, returns 0. On error, -errno is returned.
unregisterBuffers
();
// Stage the payload into the registered region and WRITE_FIXED it to the file. // prepWriteFixed(e, fd, offset, slice-of-the-registered-buffer, bufferIndex).
(local variable) ubyte[] buffer
buffer
[0 ..
(constant) string io_uring_read_write_fixed.main.payload = "io_uring fixed buffers, since Linux 5.1"
payload
.
(constant) ulong "io_uring fixed buffers, since Linux 5.1".length = 39LU
length
] = cast(const(ubyte)[])
(constant) string io_uring_read_write_fixed.main.payload = "io_uring fixed buffers, since Linux 5.1"
payload
;
(local variable) during.Uring io
io
.putWith!(
(ref SubmissionEntry e, int f, ubyte[] b) { e.prepWriteFixed(f, 0, b, 0); // bufferIndex 0, file offset 0 e.user_data = 1; })(
during.Uring during.Uring.putWith!(function (ref during.io_uring.SubmissionEntry e, int f, ubyte[] b) nothrow @nogc @safe { prepWriteFixed(e, f, 0L, b, cast(ushort)0u); e.user_data = 1LU; } , const(int), ubyte[])(ref const(int) __param_0, ubyte[] __param_1) nothrow @nogc return ref @safe

Adds new entry to the SubmissionQueue.

Note that this just adds entry to the queue and doesn't advance the tail marker kernel sees. For that finishSq() is needed to be called next.

Also note that to actually enter new entries to kernel, it's needed to call submit().

@paramFN Function to fill next entry in queue by ref (should be faster). It is expected to be in a form of void function(ARGS)(ref SubmissionEntry, auto ref ARGS). Note that in this case queue entry is cleaned first before function is called.@paramentry Custom built SubmissionEntry to be posted as is. Note that in this case it is copied whole over one in the SubmissionQueue.@paramargs Optional arguments passed to the function@returnsreference to Uring structure so it's possible to chain multiple commands.
fd
,
during.Uring during.Uring.putWith!(function (ref during.io_uring.SubmissionEntry e, int f, ubyte[] b) nothrow @nogc @safe { prepWriteFixed(e, f, 0L, b, cast(ushort)0u); e.user_data = 1LU; } , const(int), ubyte[])(ref const(int) __param_0, ubyte[] __param_1) nothrow @nogc return ref @safe

Adds new entry to the SubmissionQueue.

Note that this just adds entry to the queue and doesn't advance the tail marker kernel sees. For that finishSq() is needed to be called next.

Also note that to actually enter new entries to kernel, it's needed to call submit().

@paramFN Function to fill next entry in queue by ref (should be faster). It is expected to be in a form of void function(ARGS)(ref SubmissionEntry, auto ref ARGS). Note that in this case queue entry is cleaned first before function is called.@paramentry Custom built SubmissionEntry to be posted as is. Note that in this case it is copied whole over one in the SubmissionQueue.@paramargs Optional arguments passed to the function@returnsreference to Uring structure so it's possible to chain multiple commands.
buffer
[0 ..
(constant) string io_uring_read_write_fixed.main.payload = "io_uring fixed buffers, since Linux 5.1"
payload
.
(constant) ulong "io_uring fixed buffers, since Linux 5.1".length = 39LU
length
]);
auto
(local variable) int submitted
submitted
=
(local variable) during.Uring io
io
.
int during.Uring.submit(uint want) nothrow @nogc @safe

Submits qued SubmissionEntry to be processed by kernel.

@paramwant number of CompletionEntries to wait for. If 0, this just submits queued entries and returns. If > 0, it blocks until at least wanted number of entries were completed.@paramsig See io_uring_enter(2) man page@returnsNumber of submitted entries on success, -errno on error
submit
(1);
if (
(local variable) int submitted
submitted
< 0)
{ stderr.
std.stdio.File std.stdio.makeGlobal!"core.stdc.stdio.stderr"() nothrow @nogc @property ref @system
writefln
("submit (write) failed: errno %d", -
(local variable) int submitted
submitted
);
return 1; }
(local variable) during.Uring io
io
.
int during.Uring.wait(uint want = 1u) nothrow @nogc

Simmilar to submit but with this method we just wait for required number of CompletionEntries.

@returns0 on success, -errno on error
wait
(1);
auto
(local variable) int wres
wres
=
(local variable) during.Uring io
io
.
during.io_uring.CompletionEntry during.Uring.front() pure nothrow @nogc return ref @safe

Get first CompletionEntry from cq ring

front
.
(field) int during.io_uring.CompletionEntry.res

result code for this event

res
;
(local variable) during.Uring io
io
.
void during.Uring.popFront() pure nothrow @nogc @safe

Move to next CompletionEntry

popFront
();
// *_FIXED can report -EINVAL/-EOPNOTSUPP if fixed buffers are unavailable in this // environment (e.g. a restrictive sandbox) — treat that as an honest SKIP. if (
(local variable) int wres
wres
== -
(constant) int core.stdc.errno.EINVAL = 22
EINVAL
||
(local variable) int wres
wres
== -
(constant) int core.stdc.errno.EOPNOTSUPP = 95
EOPNOTSUPP
||
(local variable) int wres
wres
== -
(constant) int core.stdc.errno.ENOSYS = 38
ENOSYS
)
{
void std.stdio.writefln!(char, int)(in char[] fmt, int __param_1) @safe

Equivalent to writef(fmt, args, '\n').

writefln
("SKIP: WRITE_FIXED unsupported here (errno %d)", -
(local variable) int wres
wres
);
return 0; } if (
(local variable) int wres
wres
< 0)
{ stderr.
std.stdio.File std.stdio.makeGlobal!"core.stdc.stdio.stderr"() nothrow @nogc @property ref @system
writefln
("WRITE_FIXED failed: errno %d", -
(local variable) int wres
wres
);
return 1; } if (
(local variable) int wres
wres
!= cast(int)
(constant) string io_uring_read_write_fixed.main.payload = "io_uring fixed buffers, since Linux 5.1"
payload
.
(constant) ulong "io_uring fixed buffers, since Linux 5.1".length = 39LU
length
)
{ stderr.
std.stdio.File std.stdio.makeGlobal!"core.stdc.stdio.stderr"() nothrow @nogc @property ref @system
writefln
("WRITE_FIXED short write: wrote %d of %d bytes",
(local variable) int wres
wres
,
(constant) string io_uring_read_write_fixed.main.payload = "io_uring fixed buffers, since Linux 5.1"
payload
.
(constant) ulong "io_uring fixed buffers, since Linux 5.1".length = 39LU
length
);
return 1; } // Clear the registered region so the read genuinely round-trips through the file, // not through stale buffer contents.
(local variable) ubyte[] buffer
buffer
[0 ..
(constant) string io_uring_read_write_fixed.main.payload = "io_uring fixed buffers, since Linux 5.1"
payload
.
(constant) ulong "io_uring fixed buffers, since Linux 5.1".length = 39LU
length
] = 0;
(local variable) during.Uring io
io
.putWith!(
(ref SubmissionEntry e, int f, ubyte[] b) { e.prepReadFixed(f, 0, b, 0); // bufferIndex 0, file offset 0 e.user_data = 2; })(
during.Uring during.Uring.putWith!(function (ref during.io_uring.SubmissionEntry e, int f, ubyte[] b) nothrow @nogc @safe { prepReadFixed(e, f, 0L, b, cast(ushort)0u); e.user_data = 2LU; } , const(int), ubyte[])(ref const(int) __param_0, ubyte[] __param_1) nothrow @nogc return ref @safe

Adds new entry to the SubmissionQueue.

Note that this just adds entry to the queue and doesn't advance the tail marker kernel sees. For that finishSq() is needed to be called next.

Also note that to actually enter new entries to kernel, it's needed to call submit().

@paramFN Function to fill next entry in queue by ref (should be faster). It is expected to be in a form of void function(ARGS)(ref SubmissionEntry, auto ref ARGS). Note that in this case queue entry is cleaned first before function is called.@paramentry Custom built SubmissionEntry to be posted as is. Note that in this case it is copied whole over one in the SubmissionQueue.@paramargs Optional arguments passed to the function@returnsreference to Uring structure so it's possible to chain multiple commands.
fd
,
during.Uring during.Uring.putWith!(function (ref during.io_uring.SubmissionEntry e, int f, ubyte[] b) nothrow @nogc @safe { prepReadFixed(e, f, 0L, b, cast(ushort)0u); e.user_data = 2LU; } , const(int), ubyte[])(ref const(int) __param_0, ubyte[] __param_1) nothrow @nogc return ref @safe

Adds new entry to the SubmissionQueue.

Note that this just adds entry to the queue and doesn't advance the tail marker kernel sees. For that finishSq() is needed to be called next.

Also note that to actually enter new entries to kernel, it's needed to call submit().

@paramFN Function to fill next entry in queue by ref (should be faster). It is expected to be in a form of void function(ARGS)(ref SubmissionEntry, auto ref ARGS). Note that in this case queue entry is cleaned first before function is called.@paramentry Custom built SubmissionEntry to be posted as is. Note that in this case it is copied whole over one in the SubmissionQueue.@paramargs Optional arguments passed to the function@returnsreference to Uring structure so it's possible to chain multiple commands.
buffer
[0 ..
(constant) string io_uring_read_write_fixed.main.payload = "io_uring fixed buffers, since Linux 5.1"
payload
.
(constant) ulong "io_uring fixed buffers, since Linux 5.1".length = 39LU
length
]);
(local variable) int submitted
submitted
=
(local variable) during.Uring io
io
.
int during.Uring.submit(uint want) nothrow @nogc @safe

Submits qued SubmissionEntry to be processed by kernel.

@paramwant number of CompletionEntries to wait for. If 0, this just submits queued entries and returns. If > 0, it blocks until at least wanted number of entries were completed.@paramsig See io_uring_enter(2) man page@returnsNumber of submitted entries on success, -errno on error
submit
(1);
if (
(local variable) int submitted
submitted
< 0)
{ stderr.
std.stdio.File std.stdio.makeGlobal!"core.stdc.stdio.stderr"() nothrow @nogc @property ref @system
writefln
("submit (read) failed: errno %d", -
(local variable) int submitted
submitted
);
return 1; }
(local variable) during.Uring io
io
.
int during.Uring.wait(uint want = 1u) nothrow @nogc

Simmilar to submit but with this method we just wait for required number of CompletionEntries.

@returns0 on success, -errno on error
wait
(1);
auto
(local variable) int rres
rres
=
(local variable) during.Uring io
io
.
during.io_uring.CompletionEntry during.Uring.front() pure nothrow @nogc return ref @safe

Get first CompletionEntry from cq ring

front
.
(field) int during.io_uring.CompletionEntry.res

result code for this event

res
;
(local variable) during.Uring io
io
.
void during.Uring.popFront() pure nothrow @nogc @safe

Move to next CompletionEntry

popFront
();
if (
(local variable) int rres
rres
== -
(constant) int core.stdc.errno.EINVAL = 22
EINVAL
||
(local variable) int rres
rres
== -
(constant) int core.stdc.errno.EOPNOTSUPP = 95
EOPNOTSUPP
||
(local variable) int rres
rres
== -
(constant) int core.stdc.errno.ENOSYS = 38
ENOSYS
)
{
void std.stdio.writefln!(char, int)(in char[] fmt, int __param_1) @safe

Equivalent to writef(fmt, args, '\n').

writefln
("SKIP: READ_FIXED unsupported here (errno %d)", -
(local variable) int rres
rres
);
return 0; } if (
(local variable) int rres
rres
< 0)
{ stderr.
std.stdio.File std.stdio.makeGlobal!"core.stdc.stdio.stderr"() nothrow @nogc @property ref @system
writefln
("READ_FIXED failed: errno %d", -
(local variable) int rres
rres
);
return 1; } if (
(local variable) int rres
rres
!= cast(int)
(constant) string io_uring_read_write_fixed.main.payload = "io_uring fixed buffers, since Linux 5.1"
payload
.
(constant) ulong "io_uring fixed buffers, since Linux 5.1".length = 39LU
length
)
{ stderr.
std.stdio.File std.stdio.makeGlobal!"core.stdc.stdio.stderr"() nothrow @nogc @property ref @system
writefln
("READ_FIXED short read: read %d of %d bytes",
(local variable) int rres
rres
,
(constant) string io_uring_read_write_fixed.main.payload = "io_uring fixed buffers, since Linux 5.1"
payload
.
(constant) ulong "io_uring fixed buffers, since Linux 5.1".length = 39LU
length
);
return 1; } if (cast(const(char)[])
(local variable) ubyte[] buffer
buffer
[0 ..
(constant) string io_uring_read_write_fixed.main.payload = "io_uring fixed buffers, since Linux 5.1"
payload
.
(constant) ulong "io_uring fixed buffers, since Linux 5.1".length = 39LU
length
] !=
(constant) string io_uring_read_write_fixed.main.payload = "io_uring fixed buffers, since Linux 5.1"
payload
)
{ stderr.
std.stdio.File std.stdio.makeGlobal!"core.stdc.stdio.stderr"() nothrow @nogc @property ref @system
writefln
("round-trip mismatch: got %s", cast(const(char)[])
(local variable) ubyte[] buffer
buffer
[0 ..
(constant) string io_uring_read_write_fixed.main.payload = "io_uring fixed buffers, since Linux 5.1"
payload
.
(constant) ulong "io_uring fixed buffers, since Linux 5.1".length = 39LU
length
]);
return 1; }
void std.stdio.writefln!(char, int)(in char[] fmt, int __param_1) @safe

Equivalent to writef(fmt, args, '\n').

writefln
(
"ok: WRITE_FIXED then READ_FIXED round-tripped %d bytes through a registered buffer (index 0)",
(local variable) int rres
rres
);
return 0; } // `octal!"600"` — compile-time octal literal for the file mode, avoiding a leading-0 // literal (deprecated in D) while keeping the intent obvious. private template
(template) io_uring_read_write_fixed.octal(string s)
octal
(string s)
{ enum uint
(constant) uint io_uring_read_write_fixed.octal!"600" = 384u
octal
=
uint io_uring_read_write_fixed.parseOctal(string s) pure nothrow @nogc @safe
parseOctal
(
(constant) string io_uring_read_write_fixed.s = "600"
s
);
} private uint
uint io_uring_read_write_fixed.parseOctal(string s) pure nothrow @nogc @safe
parseOctal
(
(alias) object.string = string
string
(parameter) string s
s
) pure nothrow @safe @nogc
{ uint
(local variable) uint v
v
;
foreach (
(parameter) immutable(char) c
c
;
(parameter) string s
s
)
(local variable) uint v
v
=
(local variable) uint v
v
* 8 + (
(local variable) immutable(char) c
c
- '0');
return
(local variable) uint v
v
;
}