mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
IoUring: use the splice flags type for splice and tee
Use appropriately sized integers where applicable Signed-off-by: Bernard Assan <mega.alpha100@gmail.com>
This commit is contained in:
parent
f6be2c37c6
commit
23e3753ca7
1 changed files with 80 additions and 34 deletions
|
|
@ -424,25 +424,32 @@ pub fn splice(
|
||||||
off_in: u64,
|
off_in: u64,
|
||||||
fd_out: linux.fd_t,
|
fd_out: linux.fd_t,
|
||||||
off_out: u64,
|
off_out: u64,
|
||||||
len: usize,
|
len: u32,
|
||||||
|
flags: uflags.Splice,
|
||||||
) !*Sqe {
|
) !*Sqe {
|
||||||
const sqe = try self.get_sqe();
|
const sqe = try self.get_sqe();
|
||||||
sqe.prep_splice(fd_in, off_in, fd_out, off_out, len);
|
sqe.prep_splice(
|
||||||
|
fd_in,
|
||||||
|
off_in,
|
||||||
|
fd_out,
|
||||||
|
off_out,
|
||||||
|
len,
|
||||||
|
flags,
|
||||||
|
);
|
||||||
sqe.user_data = user_data;
|
sqe.user_data = user_data;
|
||||||
return sqe;
|
return sqe;
|
||||||
}
|
}
|
||||||
|
|
||||||
// COMMIT: ignored flags for splice and tee lets see if they become important
|
|
||||||
// in the future
|
|
||||||
pub fn tee(
|
pub fn tee(
|
||||||
self: *IoUring,
|
self: *IoUring,
|
||||||
user_data: u64,
|
user_data: u64,
|
||||||
fd_in: linux.fd_t,
|
fd_in: linux.fd_t,
|
||||||
fd_out: linux.fd_t,
|
fd_out: linux.fd_t,
|
||||||
len: usize,
|
len: u32,
|
||||||
|
flags: uflags.Splice,
|
||||||
) !*Sqe {
|
) !*Sqe {
|
||||||
const sqe = try self.get_sqe();
|
const sqe = try self.get_sqe();
|
||||||
sqe.prep_tee(fd_in, fd_out, len);
|
sqe.prep_tee(fd_in, fd_out, len, flags);
|
||||||
sqe.user_data = user_data;
|
sqe.user_data = user_data;
|
||||||
return sqe;
|
return sqe;
|
||||||
}
|
}
|
||||||
|
|
@ -759,8 +766,6 @@ pub fn timeout_update(
|
||||||
/// Queues (but does not submit) an SQE to perform an `accept4(2)` on a socket.
|
/// Queues (but does not submit) an SQE to perform an `accept4(2)` on a socket.
|
||||||
/// Returns a pointer to the SQE.
|
/// Returns a pointer to the SQE.
|
||||||
/// Available since 5.5
|
/// Available since 5.5
|
||||||
// TODO: can't we make the sockaddr and socklen_t combo in our api better?
|
|
||||||
// Investigate this
|
|
||||||
pub fn accept(
|
pub fn accept(
|
||||||
self: *IoUring,
|
self: *IoUring,
|
||||||
user_data: u64,
|
user_data: u64,
|
||||||
|
|
@ -939,7 +944,7 @@ pub fn listen(
|
||||||
self: *IoUring,
|
self: *IoUring,
|
||||||
user_data: u64,
|
user_data: u64,
|
||||||
fd: linux.fd_t,
|
fd: linux.fd_t,
|
||||||
backlog: usize,
|
backlog: u32,
|
||||||
// liburing doesn't have this flag, hence 0 should be passed
|
// liburing doesn't have this flag, hence 0 should be passed
|
||||||
// TODO: consider removing this and all flags like this
|
// TODO: consider removing this and all flags like this
|
||||||
flags: u32,
|
flags: u32,
|
||||||
|
|
@ -1339,21 +1344,24 @@ pub fn recv_multishot(
|
||||||
/// buffer_selection.
|
/// buffer_selection.
|
||||||
///
|
///
|
||||||
/// The kernel expects a contiguous block of memory of size (buffers_count *
|
/// The kernel expects a contiguous block of memory of size (buffers_count *
|
||||||
/// buffer_size).
|
/// buffer_len).
|
||||||
// TODO: why not use a slice with `buffers_count`
|
|
||||||
pub fn provide_buffers(
|
pub fn provide_buffers(
|
||||||
self: *IoUring,
|
self: *IoUring,
|
||||||
user_data: u64,
|
user_data: u64,
|
||||||
|
/// an array of `buffers_count` buffers of len `buffer_len` laid out as a
|
||||||
|
/// contiguous slice of memory
|
||||||
buffers: [*]u8,
|
buffers: [*]u8,
|
||||||
buffer_size: usize,
|
/// lenght of each buffer in `buffers`
|
||||||
buffers_count: usize,
|
buffer_len: u32,
|
||||||
group_id: usize,
|
/// count of buffer in `buffers`
|
||||||
buffer_id: usize,
|
buffers_count: u32,
|
||||||
|
group_id: u32,
|
||||||
|
buffer_id: u32,
|
||||||
) !*Sqe {
|
) !*Sqe {
|
||||||
const sqe = try self.get_sqe();
|
const sqe = try self.get_sqe();
|
||||||
sqe.prep_provide_buffers(
|
sqe.prep_provide_buffers(
|
||||||
buffers,
|
buffers,
|
||||||
buffer_size,
|
buffer_len,
|
||||||
buffers_count,
|
buffers_count,
|
||||||
group_id,
|
group_id,
|
||||||
buffer_id,
|
buffer_id,
|
||||||
|
|
@ -1367,8 +1375,8 @@ pub fn provide_buffers(
|
||||||
pub fn remove_buffers(
|
pub fn remove_buffers(
|
||||||
self: *IoUring,
|
self: *IoUring,
|
||||||
user_data: u64,
|
user_data: u64,
|
||||||
buffers_count: usize,
|
buffers_count: u32,
|
||||||
group_id: usize,
|
group_id: u32,
|
||||||
) !*Sqe {
|
) !*Sqe {
|
||||||
const sqe = try self.get_sqe();
|
const sqe = try self.get_sqe();
|
||||||
sqe.prep_remove_buffers(buffers_count, group_id);
|
sqe.prep_remove_buffers(buffers_count, group_id);
|
||||||
|
|
@ -2550,26 +2558,54 @@ pub const Sqe = extern struct {
|
||||||
sqe.prep_rw(.writev, fd, @intFromPtr(iovecs.ptr), iovecs.len, offset);
|
sqe.prep_rw(.writev, fd, @intFromPtr(iovecs.ptr), iovecs.len, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prep_write_fixed(sqe: *Sqe, fd: linux.fd_t, buffer: []const u8, offset: u64, buffer_index: u16) void {
|
pub fn prep_write_fixed(
|
||||||
|
sqe: *Sqe,
|
||||||
|
fd: linux.fd_t,
|
||||||
|
buffer: []const u8,
|
||||||
|
offset: u64,
|
||||||
|
buffer_index: u16,
|
||||||
|
) void {
|
||||||
sqe.prep_rw(.write_fixed, fd, @intFromPtr(buffer.ptr), buffer.len, offset);
|
sqe.prep_rw(.write_fixed, fd, @intFromPtr(buffer.ptr), buffer.len, offset);
|
||||||
sqe.buf_index = buffer_index;
|
sqe.buf_index = buffer_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prep_writev_fixed(sqe: *Sqe, fd: linux.fd_t, iovecs: []const posix.iovec_const, offset: u64, buffer_index: u16) void {
|
pub fn prep_writev_fixed(
|
||||||
|
sqe: *Sqe,
|
||||||
|
fd: linux.fd_t,
|
||||||
|
iovecs: []const posix.iovec_const,
|
||||||
|
offset: u64,
|
||||||
|
buffer_index: u16,
|
||||||
|
) void {
|
||||||
sqe.prep_rw(.write_fixed, fd, @intFromPtr(iovecs.ptr), iovecs.len, offset);
|
sqe.prep_rw(.write_fixed, fd, @intFromPtr(iovecs.ptr), iovecs.len, offset);
|
||||||
sqe.buf_index = buffer_index;
|
sqe.buf_index = buffer_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prep_splice(sqe: *Sqe, fd_in: linux.fd_t, off_in: u64, fd_out: linux.fd_t, off_out: u64, len: usize) void {
|
pub fn prep_splice(
|
||||||
|
sqe: *Sqe,
|
||||||
|
fd_in: linux.fd_t,
|
||||||
|
off_in: u64,
|
||||||
|
fd_out: linux.fd_t,
|
||||||
|
off_out: u64,
|
||||||
|
len: u32,
|
||||||
|
flags: uflags.Splice,
|
||||||
|
) void {
|
||||||
sqe.prep_rw(.splice, fd_out, undefined, len, off_out);
|
sqe.prep_rw(.splice, fd_out, undefined, len, off_out);
|
||||||
sqe.addr = off_in;
|
sqe.addr = off_in;
|
||||||
sqe.splice_fd_in = fd_in;
|
sqe.splice_fd_in = fd_in;
|
||||||
|
sqe.rw_flags = @bitCast(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prep_tee(sqe: *Sqe, fd_in: linux.fd_t, fd_out: linux.fd_t, len: usize) void {
|
pub fn prep_tee(
|
||||||
|
sqe: *Sqe,
|
||||||
|
fd_in: linux.fd_t,
|
||||||
|
fd_out: linux.fd_t,
|
||||||
|
len: u32,
|
||||||
|
flags: uflags.Splice,
|
||||||
|
) void {
|
||||||
sqe.prep_rw(.tee, fd_out, undefined, len, 0);
|
sqe.prep_rw(.tee, fd_out, undefined, len, 0);
|
||||||
sqe.addr = undefined;
|
sqe.addr = undefined;
|
||||||
sqe.splice_fd_in = fd_in;
|
sqe.splice_fd_in = fd_in;
|
||||||
|
sqe.rw_flags = @bitCast(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prep_read(sqe: *Sqe, fd: linux.fd_t, buffer: []u8, offset: u64) void {
|
pub fn prep_read(sqe: *Sqe, fd: linux.fd_t, buffer: []u8, offset: u64) void {
|
||||||
|
|
@ -3260,24 +3296,34 @@ pub const Sqe = extern struct {
|
||||||
sqe.prep_rw(.files_update, -1, @intFromPtr(fds.ptr), fds.len, constants.FILE_INDEX_ALLOC);
|
sqe.prep_rw(.files_update, -1, @intFromPtr(fds.ptr), fds.len, constants.FILE_INDEX_ALLOC);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: why can't slice be used here ?
|
// Note: It is more appropriate to use a `[*]u8` than `[]u8` slice here
|
||||||
|
// because `[]u8` would free us of the extra `buffer_len` parameter but
|
||||||
|
// would require us to alway calculate the `buffer_len` in the function
|
||||||
|
// which is redundant since the `buffer_len` and `buffers_count`
|
||||||
|
// information are alway available for any 2 dimentional array type
|
||||||
|
// .ie [buffers_count][buffer_len]u8
|
||||||
pub fn prep_provide_buffers(
|
pub fn prep_provide_buffers(
|
||||||
sqe: *Sqe,
|
sqe: *Sqe,
|
||||||
buffers: [*]u8,
|
buffers: [*]u8,
|
||||||
buffer_len: usize,
|
buffer_len: u32,
|
||||||
num: usize,
|
buffers_count: u32,
|
||||||
group_id: usize,
|
group_id: u32,
|
||||||
buffer_id: usize,
|
buffer_id: u32,
|
||||||
) void {
|
) void {
|
||||||
const ptr = @intFromPtr(buffers);
|
sqe.prep_rw(
|
||||||
sqe.prep_rw(.provide_buffers, @intCast(num), ptr, buffer_len, buffer_id);
|
.provide_buffers,
|
||||||
|
@intCast(buffers_count),
|
||||||
|
@intFromPtr(buffers),
|
||||||
|
buffer_len,
|
||||||
|
buffer_id,
|
||||||
|
);
|
||||||
sqe.buf_index = @intCast(group_id);
|
sqe.buf_index = @intCast(group_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prep_remove_buffers(
|
pub fn prep_remove_buffers(
|
||||||
sqe: *Sqe,
|
sqe: *Sqe,
|
||||||
num: usize,
|
num: u32,
|
||||||
group_id: usize,
|
group_id: u32,
|
||||||
) void {
|
) void {
|
||||||
sqe.prep_rw(.remove_buffers, @intCast(num), 0, 0, 0);
|
sqe.prep_rw(.remove_buffers, @intCast(num), 0, 0, 0);
|
||||||
sqe.buf_index = @intCast(group_id);
|
sqe.buf_index = @intCast(group_id);
|
||||||
|
|
@ -3478,7 +3524,7 @@ pub const Sqe = extern struct {
|
||||||
pub fn prep_listen(
|
pub fn prep_listen(
|
||||||
sqe: *Sqe,
|
sqe: *Sqe,
|
||||||
fd: linux.fd_t,
|
fd: linux.fd_t,
|
||||||
backlog: usize,
|
backlog: u32,
|
||||||
flags: u32, // flags is unused and does't exist in io_uring's api
|
flags: u32, // flags is unused and does't exist in io_uring's api
|
||||||
) void {
|
) void {
|
||||||
sqe.prep_rw(.listen, fd, 0, backlog, 0);
|
sqe.prep_rw(.listen, fd, 0, backlog, 0);
|
||||||
|
|
@ -5044,13 +5090,13 @@ test "splice/read" {
|
||||||
const fds = try posix.pipe();
|
const fds = try posix.pipe();
|
||||||
const pipe_offset: u64 = math.maxInt(u64);
|
const pipe_offset: u64 = math.maxInt(u64);
|
||||||
|
|
||||||
const sqe_splice_to_pipe = try ring.splice(0x11111111, fd_src, 0, fds[1], pipe_offset, buffer_write.len);
|
const sqe_splice_to_pipe = try ring.splice(0x11111111, fd_src, 0, fds[1], pipe_offset, buffer_write.len, .{});
|
||||||
try testing.expectEqual(Op.splice, sqe_splice_to_pipe.opcode);
|
try testing.expectEqual(Op.splice, sqe_splice_to_pipe.opcode);
|
||||||
try testing.expectEqual(0, sqe_splice_to_pipe.addr);
|
try testing.expectEqual(0, sqe_splice_to_pipe.addr);
|
||||||
try testing.expectEqual(pipe_offset, sqe_splice_to_pipe.off);
|
try testing.expectEqual(pipe_offset, sqe_splice_to_pipe.off);
|
||||||
sqe_splice_to_pipe.link_next();
|
sqe_splice_to_pipe.link_next();
|
||||||
|
|
||||||
const sqe_splice_from_pipe = try ring.splice(0x22222222, fds[0], pipe_offset, fd_dst, 10, buffer_write.len);
|
const sqe_splice_from_pipe = try ring.splice(0x22222222, fds[0], pipe_offset, fd_dst, 10, buffer_write.len, .{});
|
||||||
try testing.expectEqual(Op.splice, sqe_splice_from_pipe.opcode);
|
try testing.expectEqual(Op.splice, sqe_splice_from_pipe.opcode);
|
||||||
try testing.expectEqual(pipe_offset, sqe_splice_from_pipe.addr);
|
try testing.expectEqual(pipe_offset, sqe_splice_from_pipe.addr);
|
||||||
try testing.expectEqual(10, sqe_splice_from_pipe.off);
|
try testing.expectEqual(10, sqe_splice_from_pipe.off);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue