Skip to content

Commit c95951d

Browse files
authored
Merge pull request #122 from talex5/setup-flags
Add Uring.Setup_flags
2 parents 0422ca4 + 11fdb93 commit c95951d

File tree

6 files changed

+95
-24
lines changed

6 files changed

+95
-24
lines changed

lib/uring/heap.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ type ptr = private int
2828

2929
val ptr : 'a entry -> ptr
3030
(** [ptr e] is the index of [e].
31-
@raise Invalid_arg if [e] has already been freed. *)
31+
@raise Invalid_argument if [e] has already been freed. *)
3232

3333
val alloc : 'a t -> 'a -> extra_data:'b -> 'a entry
3434
(** [alloc t a ~extra_data] adds the value [a] to [t] and returns a

lib/uring/include/discover.ml

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,24 @@ let uring_ops = [
9999
"IORING_OP_URING_CMD";
100100
]
101101

102-
let ops c =
102+
let uring_setup_flags = [
103+
"IORING_SETUP_IOPOLL";
104+
(* "IORING_SETUP_SQPOLL" *) (* Enabled by passing a polling timeout instead *)
105+
(* "IORING_SETUP_SQ_AFF"; *) (* todo: requires setting sq_thread_cpu too *)
106+
(* "IORING_SETUP_CQSIZE"; *) (* todo: requires setting cq_entries *)
107+
"IORING_SETUP_CLAMP";
108+
(* "IORING_SETUP_ATTACH_WQ"; *) (* todo: requires setting wq_fd *)
109+
"IORING_SETUP_R_DISABLED";
110+
"IORING_SETUP_SUBMIT_ALL";
111+
"IORING_SETUP_COOP_TASKRUN";
112+
"IORING_SETUP_TASKRUN_FLAG";
113+
"IORING_SETUP_SQE128";
114+
"IORING_SETUP_CQE32";
115+
"IORING_SETUP_SINGLE_ISSUER";
116+
"IORING_SETUP_DEFER_TASKRUN";
117+
]
118+
119+
let uring_defs c =
103120
Gen.abstract_module "Op" (
104121
C.C_define.import c (List.map (fun name -> name, C.C_define.Type.Int) uring_ops)
105122
~c_flags:["-D_GNU_SOURCE"; "-I"; include_dir]
@@ -111,6 +128,18 @@ let ops c =
111128
(ocaml_name, v)
112129
| _ -> assert false
113130
)
131+
) @
132+
Gen.hex_module "Ioring_setup" (
133+
C.C_define.import c (List.map (fun name -> name, C.C_define.Type.Int) uring_setup_flags)
134+
~c_flags:["-D_GNU_SOURCE"; "-I"; include_dir]
135+
~includes:["liburing.h"]
136+
|> List.map (function
137+
| name, C.C_define.Value.Int v ->
138+
let prefix_len = String.length "IORING_SETUP_" in
139+
let ocaml_name = String.sub name prefix_len (String.length name - prefix_len) |> String.lowercase_ascii in
140+
(ocaml_name, v)
141+
| _ -> assert false
142+
)
114143
)
115144

116145
let stat_flags c =
@@ -199,7 +228,7 @@ let () =
199228
C.main ~name:"discover" (fun c ->
200229
C.Flags.write_lines "config.ml" @@ List.flatten @@ List.map (fun f -> f c) [
201230
toplevel_defs;
202-
ops;
231+
uring_defs;
203232
stat_flags;
204233
]
205234
)

lib/uring/primitives.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ CAMLprim value ocaml_uring_set_iovec(value, value);
5757
CAMLprim value ocaml_uring_set_string(value, value);
5858
CAMLprim value ocaml_uring_make_msghdr(value, value, value);
5959
CAMLprim value ocaml_uring_get_msghdr_fds(value);
60-
CAMLprim value ocaml_uring_setup(value, value);
60+
CAMLprim value ocaml_uring_setup(value, value, value);
6161
CAMLprim value ocaml_uring_exit(value);
6262
CAMLprim value ocaml_uring_unregister_buffers(value);
6363
CAMLprim value ocaml_uring_register_ba(value, value);

lib/uring/uring.ml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@ module Poll_mask = struct
8686
let pollhup = Config.pollhup
8787
end
8888

89+
module Setup_flags = struct
90+
include Flags
91+
include Config.Ioring_setup
92+
end
93+
8994
module Statx = struct
9095
type t
9196

@@ -299,7 +304,7 @@ type probe
299304
module Uring = struct
300305
type t
301306

302-
external create : int -> int option -> t = "ocaml_uring_setup"
307+
external create : int -> int option -> Setup_flags.t -> t = "ocaml_uring_setup"
303308
external exit : t -> unit = "ocaml_uring_exit"
304309

305310
external unregister_buffers : t -> unit = "ocaml_uring_unregister_buffers"
@@ -394,9 +399,9 @@ let register_gc_root t =
394399
let unregister_gc_root t =
395400
update_gc_roots (Ring_set.remove (Generic_ring.T t))
396401

397-
let create ?polling_timeout ~queue_depth () =
402+
let create ?(flags=Setup_flags.empty) ?polling_timeout ~queue_depth () =
398403
if queue_depth < 1 then Fmt.invalid_arg "Non-positive queue depth: %d" queue_depth;
399-
let uring = Uring.create queue_depth polling_timeout in
404+
let uring = Uring.create queue_depth polling_timeout flags in
400405
let data = Heap.create queue_depth in
401406
let id = object end in
402407
let fixed_iobuf = Cstruct.empty.buffer in

lib/uring/uring.mli

Lines changed: 52 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,65 @@
2323

2424
module Region = Region
2525

26+
(** Type of flags that can be combined. *)
27+
module type FLAGS = sig
28+
type t = private int
29+
(** A set of flags. *)
30+
31+
val empty : t
32+
33+
val of_int : int -> t
34+
35+
val ( + ) : t -> t -> t
36+
(** [a + b] is the union of the sets. *)
37+
38+
val mem : t -> t -> bool
39+
(** [mem x flags] is [true] iff [x] is a subset of [flags]. *)
40+
end
41+
42+
(** Flags that can be passed to {!create}. *)
43+
module Setup_flags : sig
44+
include FLAGS
45+
46+
val iopoll : t
47+
(** io_context is polled *)
48+
49+
val clamp : t
50+
(** Clamp SQ/CQ ring sizes *)
51+
52+
val r_disabled : t
53+
(** Start with ring disabled *)
54+
55+
val submit_all : t
56+
(** Continue submit on error *)
57+
58+
val coop_taskrun : t
59+
(** Cooperative task running *)
60+
61+
val taskrun_flag : t
62+
(** Get notified if task work is available *)
63+
64+
val sqe128 : t
65+
(** SQEs are 128 byte *)
66+
67+
val cqe32 : t
68+
(** CQEs are 32 byte *)
69+
70+
val single_issuer : t
71+
(** Only one task is allowed to submit requests *)
72+
73+
val defer_taskrun : t
74+
(** Defer running task work to get events *)
75+
end
76+
2677
type 'a t
2778
(** ['a t] is a reference to an Io_uring structure. *)
2879

2980
type 'a job
3081
(** A handle for a submitted job, which can be used to cancel it.
3182
If an operation returns [None], this means that submission failed because the ring is full. *)
3283

33-
val create : ?polling_timeout:int -> queue_depth:int -> unit -> 'a t
84+
val create : ?flags:Setup_flags.t -> ?polling_timeout:int -> queue_depth:int -> unit -> 'a t
3485
(** [create ~queue_depth] will return a fresh Io_uring structure [t].
3586
Initially, [t] has no fixed buffer. Use {!set_fixed_buffer} if you want one.
3687
@param polling_timeout If given, use polling mode with the given idle timeout (in ms).
@@ -86,21 +137,6 @@ val timeout: ?absolute:bool -> 'a t -> clock -> int64 -> 'a -> 'a job option
86137
87138
[ns] is the timeout time in nanoseconds *)
88139

89-
module type FLAGS = sig
90-
type t = private int
91-
(** A set of flags. *)
92-
93-
val empty : t
94-
95-
val of_int : int -> t
96-
97-
val ( + ) : t -> t -> t
98-
(** [a + b] is the union of the sets. *)
99-
100-
val mem : t -> t -> bool
101-
(** [mem x flags] is [true] iff [x] is a subset of [flags]. *)
102-
end
103-
104140
(** Flags that can be passed to {!openat2}. *)
105141
module Open_flags : sig
106142
include FLAGS

lib/uring/uring_stubs.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ static struct custom_operations ring_ops = {
7777
custom_fixed_length_default
7878
};
7979

80-
value ocaml_uring_setup(value entries, value polling_timeout) {
80+
value ocaml_uring_setup(value entries, value polling_timeout, value v_flags) {
8181
CAMLparam1(entries);
8282
CAMLlocal1(v_uring);
8383
struct io_uring_params params;
@@ -90,6 +90,7 @@ value ocaml_uring_setup(value entries, value polling_timeout) {
9090
Ring_val(v_uring) = ring;
9191

9292
memset(&params, 0, sizeof(params));
93+
params.flags = Int_val(v_flags);
9394
if (Is_some(polling_timeout)) {
9495
params.flags |= IORING_SETUP_SQPOLL;
9596
params.sq_thread_idle = Int_val(Some_val(polling_timeout));

0 commit comments

Comments
 (0)