@@ -16,6 +16,8 @@ sq: Sq,
1616cq : Cq ,
1717flags : uflags.Setup ,
1818features : uflags.Features ,
19+ /// matches int_flags in liburing 
20+ init_flags : uflags.Init ,
1921
2022/// A friendly way to setup an io_uring, with default linux.io_uring_params. 
2123/// `entries` must be a power of two between 1 and 32768, although the kernel 
@@ -131,6 +133,7 @@ pub fn init_params(entries: u16, p: *Params) !IoUring {
131133        .cq  =  cq ,
132134        .flags  =  p .flags ,
133135        .features  =  p .features ,
136+         .init_flags  =  .{},
134137    };
135138}
136139
@@ -182,7 +185,7 @@ pub fn submit(self: *IoUring) !u32 {
182185/// Matches the implementation of `io_uring_submit_and_wait()` in liburing. 
183186pub  fn  submit_and_wait (self : * IoUring , wait_nr : u32 ) ! u32  {
184187    const  submitted  =  self .flush_sq ();
185-     var  flags : uflags.Enter  =  .{} ;
188+     var  flags : uflags.Enter  =  self . enter_flags () ;
186189    if  (self .sq_ring_needs_enter (& flags ) or  wait_nr  >  0 ) {
187190        if  (wait_nr  >  0  or  self .flags .iopoll ) {
188191            flags .getevents  =  true ;
@@ -264,7 +267,7 @@ pub fn flush_sq(self: *IoUring) u32 {
264267/// awakened. For the latter case, we set the SQ thread wakeup flag. 
265268/// Matches the implementation of `sq_ring_needs_enter()` in liburing. 
266269pub  fn  sq_ring_needs_enter (self : * IoUring , flags : * uflags.Enter ) bool  {
267-     assert (flags .* .empty ());
270+     assert (flags .* .valid_init_flags ());
268271    if  (! self .flags .sqpoll ) return  true ;
269272    if  (@atomicLoad (Sq .Flags , self .sq .flags , .unordered ).need_wakeup ) {
270273        flags .* .sq_wakeup  =  true ;
@@ -309,7 +312,12 @@ pub fn copy_cqes(self: *IoUring, cqes: []Cqe, wait_nr: u32) !u32 {
309312    const  count  =  self .copy_cqes_ready (cqes );
310313    if  (count  >  0 ) return  count ;
311314    if  (self .cq_ring_needs_flush () or  wait_nr  >  0 ) {
312-         _  =  try  self .enter (0 , wait_nr , .{ .getevents  =  true  });
315+         const  flags  =  blk : {
316+             var  flags  =  self .enter_flags ();
317+             flags .getevents  =  true ;
318+             break  :blk  flags ;
319+         };
320+         _  =  try  self .enter (0 , wait_nr , flags );
313321        return  self .copy_cqes_ready (cqes );
314322    }
315323    return  0 ;
@@ -374,6 +382,20 @@ pub fn cq_advance(self: *IoUring, count: u32) void {
374382    }
375383}
376384
385+ /// Enable/disable setting of iowait by the kernel. 
386+ /// matches `io_uring_set_iowait` in liburing 
387+ pub  fn  set_iowait (self : * IoUring , enable_iowait : bool ) ! void  {
388+     if  (! self .features .no_iowait ) {
389+         return  error .SystemOutdated ;
390+     }
391+     self .init_flags .no_iowait  =  ! enable_iowait ;
392+ }
393+ 
394+ /// matches `ring_enter_flags()` in liburing 
395+ pub  fn  enter_flags (self : * IoUring ) uflags.Enter  {
396+     return  self .init_flags .enter_flags ();
397+ }
398+ 
377399/// Queues (but does not submit) an SQE to perform a `splice(2)` 
378400/// Either `fd_in` or `fd_out` must be a pipe. 
379401/// If `fd_in` refers to a pipe, `off_in` is ignored and must be set to 
@@ -4190,13 +4212,41 @@ pub const uflags = struct {
41904212        no_iowait : bool  =  false ,
41914213        _9 : u24  =  0 ,
41924214
4193-         pub  fn  empty (enter_flags : Enter ) bool  {
4194-             return  @as (u32 , @bitCast (enter_flags )) ==  0 ;
4215+         /// Ensure only `Init` flags usable in `Enter` are set 
4216+         pub  fn  valid_init_flags (self : Enter ) bool  {
4217+             const  valid_flags : u32  =  @bitCast (Enter { .registered_ring  =  true , .no_iowait  =  true  });
4218+             const  flags : u32  =  @bitCast (self );
4219+             // check if any invalid flags are set 
4220+             return  (flags  & ~ valid_flags ) ==  0 ;
4221+         }
4222+ 
4223+         pub  fn  empty (flags : Enter ) bool  {
4224+             return  @as (u32 , @bitCast (flags )) ==  0 ;
4225+         }
4226+     };
4227+ 
4228+     /// matches INT_FLAG_* in liburing 
4229+     pub  const  Init  =  packed  struct (u8 ) {
4230+         reg_reg_ring : bool  =  false ,
4231+         app_mem : bool  =  false ,
4232+         cq_enter : bool  =  false ,
4233+         _4 : u1  =  0 ,
4234+         /// matches `registered_ring` flag in `Enter` 
4235+         reg_ring : bool  =  false ,
4236+         _6 : u2  =  0 ,
4237+         /// matches `no_iowait` flag in `Enter` 
4238+         no_iowait : bool  =  false ,
4239+ 
4240+         /// Return all valid `Enter` flags set in `Init` 
4241+         pub  fn  enter_flags (self : Init ) Enter  {
4242+             const  valid_flags : u8  =  @bitCast (Init { .reg_ring  =  true , .no_iowait  =  true  });
4243+             const  flags : u8  =  @bitCast (self );
4244+             return  @bitCast (@as (u32 , @intCast (flags  & valid_flags )));
41954245        }
41964246    };
41974247
41984248    /// io_uring_params.features flags 
4199-     const  Features  =  packed  struct (u32 ) {
4249+     pub   const  Features  =  packed  struct (u32 ) {
42004250        single_mmap : bool  =  false ,
42014251        nodrop : bool  =  false ,
42024252        submit_stable : bool  =  false ,
@@ -4223,6 +4273,7 @@ pub const uflags = struct {
42234273        }
42244274    };
42254275};
4276+ 
42264277/// `io_uring_register(2)` opcodes and arguments 
42274278/// matches `io_uring_register_op` in liburing 
42284279pub  const  RegisterOp  =  enum (u8 ) {
0 commit comments