uringmachine 0.4 → 0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +2 -1
  3. data/CHANGELOG.md +14 -0
  4. data/README.md +44 -1
  5. data/TODO.md +12 -3
  6. data/examples/bm_snooze.rb +89 -0
  7. data/examples/bm_write.rb +56 -0
  8. data/examples/dns_client.rb +12 -0
  9. data/examples/http_server.rb +42 -43
  10. data/examples/server_client.rb +64 -0
  11. data/examples/snooze.rb +44 -0
  12. data/examples/write_dev_null.rb +16 -0
  13. data/ext/um/extconf.rb +24 -14
  14. data/ext/um/um.c +468 -414
  15. data/ext/um/um.h +129 -39
  16. data/ext/um/um_buffer.c +49 -0
  17. data/ext/um/um_class.c +148 -24
  18. data/ext/um/um_const.c +30 -1
  19. data/ext/um/um_ext.c +4 -0
  20. data/ext/um/um_mutex_class.c +47 -0
  21. data/ext/um/um_op.c +86 -111
  22. data/ext/um/um_queue_class.c +58 -0
  23. data/ext/um/um_sync.c +273 -0
  24. data/ext/um/um_utils.c +1 -1
  25. data/lib/uringmachine/dns_resolver.rb +84 -0
  26. data/lib/uringmachine/version.rb +1 -1
  27. data/lib/uringmachine.rb +19 -3
  28. data/supressions/ruby.supp +71 -0
  29. data/test/test_um.rb +466 -47
  30. data/vendor/liburing/.gitignore +5 -0
  31. data/vendor/liburing/CHANGELOG +1 -0
  32. data/vendor/liburing/configure +32 -0
  33. data/vendor/liburing/examples/Makefile +1 -0
  34. data/vendor/liburing/examples/reg-wait.c +159 -0
  35. data/vendor/liburing/liburing.spec +1 -1
  36. data/vendor/liburing/src/include/liburing/io_uring.h +48 -2
  37. data/vendor/liburing/src/include/liburing.h +28 -2
  38. data/vendor/liburing/src/int_flags.h +10 -3
  39. data/vendor/liburing/src/liburing-ffi.map +13 -2
  40. data/vendor/liburing/src/liburing.map +9 -0
  41. data/vendor/liburing/src/queue.c +25 -16
  42. data/vendor/liburing/src/register.c +73 -4
  43. data/vendor/liburing/src/setup.c +46 -18
  44. data/vendor/liburing/src/setup.h +6 -0
  45. data/vendor/liburing/test/Makefile +7 -0
  46. data/vendor/liburing/test/cmd-discard.c +427 -0
  47. data/vendor/liburing/test/fifo-nonblock-read.c +69 -0
  48. data/vendor/liburing/test/file-exit-unreg.c +48 -0
  49. data/vendor/liburing/test/io_uring_passthrough.c +2 -0
  50. data/vendor/liburing/test/io_uring_register.c +13 -2
  51. data/vendor/liburing/test/napi-test.c +1 -1
  52. data/vendor/liburing/test/no-mmap-inval.c +1 -1
  53. data/vendor/liburing/test/read-mshot-empty.c +2 -0
  54. data/vendor/liburing/test/read-mshot-stdin.c +121 -0
  55. data/vendor/liburing/test/read-mshot.c +6 -0
  56. data/vendor/liburing/test/recvsend_bundle.c +2 -2
  57. data/vendor/liburing/test/reg-fd-only.c +1 -1
  58. data/vendor/liburing/test/reg-wait.c +251 -0
  59. data/vendor/liburing/test/regbuf-clone.c +458 -0
  60. data/vendor/liburing/test/resize-rings.c +643 -0
  61. data/vendor/liburing/test/rsrc_tags.c +1 -1
  62. data/vendor/liburing/test/sqpoll-sleep.c +39 -8
  63. data/vendor/liburing/test/sqwait.c +136 -0
  64. data/vendor/liburing/test/sync-cancel.c +8 -1
  65. data/vendor/liburing/test/timeout.c +13 -8
  66. metadata +22 -4
  67. data/examples/http_server_multishot.rb +0 -57
  68. data/examples/http_server_simpler.rb +0 -34
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9a9efd4af7de9fdb8db6888b9f6347e9dbc63aae9e26fa0f81d43984d265bd90
4
- data.tar.gz: 5289699ce1e3e173d3766e0211fc77b57f3c123e2a6e041e9e751a3bf5ce07b2
3
+ metadata.gz: 2067cd0f88d6dbc341410ca6911916f510132ee23ce3f6d5fb5978259eeaef11
4
+ data.tar.gz: f816a9478f714a3a9770740bc14fc03ae2687f2fe7d0e29cbc0b8632994bad1f
5
5
  SHA512:
6
- metadata.gz: 3cf02bbaae5a9e19b9ea994d1c2bf4b327a96121b083ca6756eca70629738f6c24aca10096bb49a0400678542232062969889ed3f0773591f5dc71f718707fef
7
- data.tar.gz: 67b368097ddecd6c9ca9ce360cc918d8e7de91ec83a00d617765c2026fbe08f16f5009b78323e9f314cd1df63a1baaa39e8887b4a90fff0cb8010d810276df7d
6
+ metadata.gz: 6e0a9ed6e6f131bf6d67a56622786893532a525f4427e134670499997c0461a4df6de3ca1cb9e70851769c1135575986468a83edfd9b5d75c7d592e41bb0ca8c
7
+ data.tar.gz: 2c73ed9a3268ea96b3a167064251d16279c531ee50e5f9c6de9aa2c56f6a70973ef04ce5d6c44f46e39309f7bf8cb3f3ff5e61bf1512ca07cc5f35b91f7303dc
@@ -32,4 +32,5 @@ jobs:
32
32
  - name: Compile C-extension
33
33
  run: bundle exec rake compile
34
34
  - name: Run tests
35
- run: bundle exec rake test
35
+ # run: bundle exec ruby test/test_um.rb --name test_read_each_raising_2
36
+ run: bundle exec rake test
data/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ # 2024-11-14 Version 0.5
2
+
3
+ - Add `#waitpid`
4
+ - Add `UM.pipe`, `UM.kernel_version`
5
+ - Add `#open`
6
+ - Fix `#spin`
7
+ - Fix handling of signal interruption.
8
+ - Reimplement and simplify um_op
9
+ - Add `UM::Queue`, `#push`, `#pop`, `#shift`, `#unshift`
10
+ - Add `UM::Mutex`, `#synchronize`
11
+ - Add `#recv_each`
12
+ - Add `#getsockopt`, `#setsockopt`
13
+ - Simplify and improve op management
14
+
1
15
  # 2024-10-06 Version 0.4
2
16
 
3
17
  - Add socket constants
data/README.md CHANGED
@@ -32,6 +32,8 @@ UringMachine is based on my experience marrying Ruby and io_uring:
32
32
  - [IOU](https://github.com/digital-fabric/iou) - a low-level asynchronous API
33
33
  for using io_uring from Ruby.
34
34
 
35
+ ### Learnings
36
+
35
37
  Some important learnings from those two projects, in no particular order:
36
38
 
37
39
  - Monkey-patching is not a good solution, long term. You need to deal with
@@ -73,7 +75,25 @@ based on the following principles:
73
75
  - Do not insist on structured concurrency, just provide the APIs necessary to
74
76
  create actors and to supervise the execution of fibers.
75
77
 
76
- ## Example
78
+ ### Cancellation
79
+
80
+ When working with io_uring, managing the life cycle of asynchronous operations
81
+ is quite tricky, especially with regards to cancellation. This is due to the
82
+ fact each operation lives on both sides of the userspace-kernel divide. This
83
+ means that when cancelling an operation, we cannot free, or dispose of any
84
+ resources associated with the operation, until we know for sure that the kernel
85
+ side is also done with the operation.
86
+
87
+ As stated above, working with fibers allows us to keep operation metadata and
88
+ associated data (such as buffers etc) on the stack, which can greatly simplify
89
+ the managing of the operation's lifetime, as well as significantly reduce heap
90
+ allocations.
91
+
92
+ When a cancellation does occur, UringMachine issues a cancellation (using
93
+ `io_uring_prep_cancel64`), and then waits for the corresponding CQE (with a
94
+ `-ECANCELED` result).
95
+
96
+ ## Short Example
77
97
 
78
98
  ```ruby
79
99
  require 'uringmachine'
@@ -94,3 +114,26 @@ loop do
94
114
  end
95
115
  end
96
116
  ```
117
+
118
+ ## Concurrent Execution
119
+
120
+ Concurrent execution is done by calling `#spin`, which creates a fiber:
121
+
122
+ ```ruby
123
+ machine = UringMachine.new
124
+
125
+ rfd, wfd = machine.pipe
126
+
127
+ f1 = machine.spin do
128
+ machine.write(wfd, 'hello')
129
+ machine.write(wfd, 'world')
130
+ machine.close(wfd)
131
+ end
132
+
133
+ bgid = machine.setup_buffer_ring(4096, 1024)
134
+ f2 = machine.spin do
135
+ machine.read_each(rfd, bgid) do |str|
136
+ puts str
137
+ end
138
+ end
139
+ ```
data/TODO.md CHANGED
@@ -1,5 +1,14 @@
1
- - splice
1
+ - splice / - tee
2
2
  - sendto
3
3
  - recvfrom
4
-
5
- - queues
4
+ - poll_add / poll_remove / poll_multishot / poll_update
5
+ - fsync
6
+ - mkdir / mkdirat
7
+ - statx
8
+ - link / linkat / unlink / unlinkat / symlink
9
+ - rename / renameat
10
+ - fadvise
11
+ - madvise
12
+ - getxattr / setxattr
13
+ - shutdown
14
+ - send_bundle / recv_bundle (kernel >= 6.10)
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/inline'
4
+
5
+ gemfile do
6
+ source 'https://rubygems.org'
7
+ gem 'uringmachine', path: '..'
8
+ gem 'benchmark-ips'
9
+ end
10
+
11
+ require 'benchmark/ips'
12
+ require 'uringmachine'
13
+
14
+ ITERATIONS = 1000
15
+
16
+ $machine = UringMachine.new
17
+
18
+ def run_snooze
19
+ count = 0
20
+ main = Fiber.current
21
+
22
+ f1 = Fiber.new do
23
+ loop do
24
+ count += 1
25
+ if count == ITERATIONS
26
+ $machine.schedule(main, nil)
27
+ break
28
+ else
29
+ $machine.snooze
30
+ end
31
+ end
32
+ end
33
+
34
+ f2 = Fiber.new do
35
+ loop do
36
+ count += 1
37
+ if count == ITERATIONS
38
+ $machine.schedule(main, nil)
39
+ break
40
+ else
41
+ $machine.snooze
42
+ end
43
+ end
44
+ end
45
+
46
+ $machine.schedule(f1, nil)
47
+ $machine.schedule(f2, nil)
48
+ $machine.yield
49
+ end
50
+
51
+ def run_raw_transfer
52
+ count = 0
53
+ main = Fiber.current
54
+ f2 = nil
55
+ f1 = Fiber.new do
56
+ loop do
57
+ count += 1
58
+ if count == ITERATIONS
59
+ main.transfer(nil)
60
+ break
61
+ else
62
+ f2.transfer(nil)
63
+ end
64
+ end
65
+ end
66
+
67
+ f2 = Fiber.new do
68
+ loop do
69
+ count += 1
70
+ if count == ITERATIONS
71
+ main.transfer(nil)
72
+ break
73
+ else
74
+ f1.transfer(nil)
75
+ end
76
+ end
77
+ end
78
+
79
+ f1.transfer(nil)
80
+ end
81
+
82
+ bm = Benchmark.ips do |x|
83
+ x.config(:time => 5, :warmup => 2)
84
+
85
+ x.report("snooze") { run_snooze }
86
+ x.report("raw transfer") { run_raw_transfer }
87
+
88
+ x.compare!
89
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/inline'
4
+
5
+ gemfile do
6
+ source 'https://rubygems.org'
7
+ gem 'uringmachine', path: '..'
8
+ gem 'benchmark'
9
+ end
10
+
11
+ require 'benchmark'
12
+ require 'uringmachine'
13
+
14
+ ITERATIONS = 100000
15
+ BUF = ('*' * 8192).freeze
16
+ FN = '/tmp/bm_write'
17
+
18
+ def run_io_write(num_threads)
19
+ FileUtils.rm(FN) rescue nil
20
+ fio = File.open(FN, 'w')
21
+
22
+ threads = num_threads.times.map do |i|
23
+ Thread.new do
24
+ ITERATIONS.times { fio.write(BUF) }
25
+ end
26
+ end
27
+ threads.each(&:join)
28
+ ensure
29
+ fio.close
30
+ end
31
+
32
+ def run_um_write(num_fibers)
33
+ FileUtils.rm(FN) rescue nil
34
+ fio = File.open(FN, 'w')
35
+ fd = fio.fileno
36
+
37
+ machine = UringMachine.new
38
+ done = UringMachine::Queue.new
39
+ num_fibers.times do
40
+ machine.spin do
41
+ ITERATIONS.times { machine.write(fd, BUF) }
42
+ machine.push(done, true)
43
+ end
44
+ end
45
+ num_fibers.times { machine.pop(done) }
46
+ ensure
47
+ fio.close
48
+ end
49
+
50
+ Benchmark.bm do |x|
51
+ [1, 2, 4, 8].each do |c|
52
+ x.report("IO (#{c} threads)") { run_io_write(c) }
53
+ x.report("UM (#{c} fibers) ") { run_um_write(c) }
54
+ puts
55
+ end
56
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../lib/uringmachine'
4
+ require 'resolv'
5
+
6
+ machine = UM.new
7
+
8
+ addrs = machine.resolve('status.realiteq.net')
9
+
10
+ puts '*' * 40
11
+ puts addrs.join("\n")
12
+ puts
@@ -1,56 +1,55 @@
1
- require_relative '../lib/iou'
2
- require 'socket'
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../lib/uringmachine'
3
4
  require 'http/parser'
4
5
 
5
- def log(msg)
6
- # return
7
- STDERR.puts msg
8
- end
6
+ @machine = UM.new
7
+ @bgid = @machine.setup_buffer_ring(4096, 1024)
9
8
 
10
- socket = TCPServer.open('127.0.0.1', 1234)
11
- log 'Listening on port 1234...'
9
+ def http_handle_connection(fd)
10
+ # puts "Accepting connection on fd #{fd}"
11
+ parser = Http::Parser.new
12
+ done = nil
13
+ parser.on_message_complete = -> do
14
+ http_send_response(fd, "Hello, world!\n")
15
+ done = true
16
+ end
12
17
 
13
- @ring = IOU::Ring.new
14
- @bg_id = @ring.setup_buffer_ring(count: 1024, size: 4096)
18
+ @machine.read_each(fd, @bgid) do
19
+ parser << _1
20
+ break if done
21
+ end
15
22
 
16
- @ring.prep_accept(fd: socket.fileno, multishot: true) do |c|
17
- setup_connection(c[:result]) if c[:result] > 0
23
+ # puts "Connection closed on fd #{fd}"
24
+ rescue => e
25
+ # puts "Error while handling connection on fd #{fd}: #{e.inspect}"
26
+ ensure
27
+ @machine.close(fd) rescue nil
18
28
  end
19
29
 
20
- def setup_connection(fd)
21
- log "Connection accepted fd #{fd}"
22
-
23
- parser = Http::Parser.new
24
- parser.on_message_complete = -> {
25
- http_send_response(fd, "Hello, world!\n") do
26
- @ring.prep_close(fd: fd)
27
- end
28
- }
29
-
30
- http_prep_read(fd, parser)
30
+ def http_send_response(fd, body)
31
+ # msg = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nConnection: keep-alive\r\nContent-Length: #{body.bytesize}\r\n\r\n#{body}"
32
+ msg = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nConnection: close\r\nContent-Length: #{body.bytesize}\r\n\r\n#{body}"
33
+ @machine.write(fd, msg)
31
34
  end
32
35
 
33
- def http_prep_read(fd, parser)
34
- buffer = +''
35
- @ring.prep_read(fd: fd, buffer: buffer, len: 4096) do |c|
36
- if c[:result] > 0
37
- http_prep_read(fd, parser)
38
- parser << buffer
39
- elsif c[:result] == 0
40
- log "Connection closed by client on fd #{fd}"
41
- else
42
- log "Got error #{c[:result]} on fd #{fd}, closing connection..."
43
- @ring.prep_close(fd: fd) do |c|
44
- log "Connection closed on fd #{fd}, result #{c[:result]}"
45
- end
46
- end
36
+ server_fd = @machine.socket(UM::AF_INET, UM::SOCK_STREAM, 0, 0)
37
+ @machine.setsockopt(server_fd, UM::SOL_SOCKET, UM::SO_REUSEADDR, true)
38
+ @machine.bind(server_fd, '127.0.0.1', 1234)
39
+ @machine.listen(server_fd, UM::SOMAXCONN)
40
+ puts 'Listening on port 1234'
41
+
42
+ @machine.spin do
43
+ @machine.accept_each(server_fd) do |fd|
44
+ @machine.spin(fd) { http_handle_connection _1 }
47
45
  end
48
46
  end
49
47
 
50
- def http_send_response(fd, body)
51
- msg = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nConnection: keep-alive\r\nContent-Length: #{body.bytesize}\r\n\r\n#{body}"
52
- @ring.prep_write(fd: fd, buffer: msg)
53
- end
48
+ main = Fiber.current
49
+ trap('SIGINT') { @machine.schedule(main, nil) }
50
+ trap('SIGTERM') { @machine.schedule(main, nil) }
54
51
 
55
- trap('SIGINT') { exit! }
56
- @ring.process_completions_loop
52
+ @machine.yield
53
+ puts "Closing server FD"
54
+ @machine.close(server_fd) rescue nil
55
+ puts "done!"
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../lib/uringmachine'
4
+
5
+ PORT = 1234
6
+
7
+ @machine = UM.new
8
+ @bgid = @machine.setup_buffer_ring(4096, 1024)
9
+
10
+ @counter = 0
11
+
12
+ def handle_connection(fd)
13
+ buf = +''
14
+ loop do
15
+ res = @machine.recv(fd, buf, 8192, 0)
16
+ break if res == 0
17
+
18
+ @machine.write(fd, buf)
19
+ @counter += 2
20
+ end
21
+ ensure
22
+ @machine.close(fd) rescue nil
23
+ end
24
+
25
+ def run_client
26
+ fd = @machine.socket(UM::AF_INET, UM::SOCK_STREAM, 0, 0)
27
+ @machine.connect(fd, '127.0.0.1', PORT)
28
+ msg = 'foo' * 30
29
+ buf = +''
30
+ loop do
31
+ @machine.send(fd, msg, msg.bytesize, 0)
32
+ res = @machine.recv(fd, buf, 8192, 0)
33
+ @counter += 2
34
+
35
+ break if res == 0
36
+ raise "Got #{res} bytes instead of #{msg.bytesize}" if res != msg.bytesize
37
+ end
38
+ end
39
+
40
+ trap('SIGINT') { exit }
41
+
42
+ server_fd = @machine.socket(UM::AF_INET, UM::SOCK_STREAM, 0, 0)
43
+ @machine.setsockopt(server_fd, UM::SOL_SOCKET, UM::SO_REUSEADDR, true)
44
+ @machine.bind(server_fd, '127.0.0.1', PORT)
45
+ @machine.listen(server_fd, UM::SOMAXCONN)
46
+ puts "Listening on port #{PORT}"
47
+
48
+ at_exit { @machine.close(server_fd) rescue nil }
49
+
50
+ 20.times do
51
+ @machine.spin { run_client }
52
+ end
53
+
54
+ @machine.spin do
55
+ @machine.accept_each(server_fd) do |fd|
56
+ @machine.spin(fd) { handle_connection _1 }
57
+ end
58
+ end
59
+
60
+ t0 = Time.now
61
+ @machine.sleep 3
62
+ t1 = Time.now
63
+ elapsed = t1 - t0
64
+ puts "Did #{@counter} ops in #{elapsed} seconds (#{(@counter / elapsed)} ops/s)"
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../lib/uringmachine'
4
+
5
+ @machine = UM.new
6
+
7
+ @counter = 0
8
+ @fiber_count = 0
9
+
10
+ def start_fiber
11
+ @fiber_count += 1
12
+ @machine.spin do
13
+ max_count = @counter + rand(1000)
14
+ puts "Start #{Fiber.current} #{max_count - @counter}"
15
+ loop do
16
+ @machine.sleep 0.001
17
+ @counter += 1
18
+ break if @counter >= max_count
19
+ end
20
+ puts "Stop #{Fiber.current}"
21
+ ensure
22
+ @fiber_count -= 1
23
+ end
24
+ end
25
+
26
+ t0 = Time.now
27
+ MAX_FIBERS = 20
28
+ MAX_TIME = 10
29
+ loop do
30
+ @machine.sleep 0.1
31
+ puts "pending: #{@machine.pending_count}"
32
+ break if (Time.now - t0) > MAX_TIME
33
+ start_fiber while @fiber_count < MAX_FIBERS
34
+ end
35
+ t1 = Time.now
36
+ elapsed = t1 - t0
37
+ rate = @counter / elapsed
38
+ puts "Did #{@counter} ops in #{elapsed} seconds (#{rate} ops/s)"
39
+
40
+ puts "Waiting for fibers... (#{@fiber_count})"
41
+ while @fiber_count > 0
42
+ @machine.sleep 0.1
43
+ end
44
+ puts "Done"
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../lib/uringmachine'
4
+
5
+ ITERATIONS = 1000
6
+ DEV_NULL = File.open('/dev/null', 'w')
7
+ FD = DEV_NULL.fileno
8
+ BUF = ('*' * 8192).freeze
9
+
10
+ $machine = UringMachine.new
11
+
12
+ def run_um_write
13
+ $machine.write(FD, BUF)
14
+ end
15
+
16
+ 1000.times { run_um_write }
data/ext/um/extconf.rb CHANGED
@@ -8,8 +8,9 @@ dir_config 'um_ext'
8
8
 
9
9
  KERNEL_INFO_RE = /Linux (\d)\.(\d+)(?:\.)?((?:\d+\.?)*)(?:\-)?([\w\-]+)?/
10
10
  def get_config
11
- config = { linux: !!(RUBY_PLATFORM =~ /linux/) }
12
- raise "UringMachine only works on Linux!" if !config[:linux]
11
+ if RUBY_PLATFORM !~ /linux/
12
+ raise "UringMachine only works on Linux!"
13
+ end
13
14
 
14
15
  kernel_info = `uname -sr`
15
16
  m = kernel_info.match(KERNEL_INFO_RE)
@@ -20,14 +21,18 @@ def get_config
20
21
  combined_version = version.to_i * 100 + major_revision.to_i
21
22
  raise "UringMachine requires kernel version 6.4 or newer!" if combined_version < 604
22
23
 
23
- config[:kernel_version] = combined_version
24
- config[:submit_all_flag] = combined_version >= 518
25
- config[:coop_taskrun_flag] = combined_version >= 519
26
- config[:single_issuer_flag] = combined_version >= 600
27
- config[:prep_bind] = combined_version >= 611
28
- config[:prep_listen] = combined_version >= 611
29
-
30
- config
24
+ {
25
+ kernel_version: combined_version,
26
+ submit_all_flag: combined_version >= 518,
27
+ coop_taskrun_flag: combined_version >= 519,
28
+ single_issuer_flag: combined_version >= 600,
29
+ prep_bind: combined_version >= 611,
30
+ prep_listen: combined_version >= 611,
31
+ prep_cmd_sock: combined_version >= 607,
32
+ prep_futex: combined_version >= 607,
33
+ prep_waitid: combined_version >= 607,
34
+ prep_read_multishot: combined_version >= 607
35
+ }
31
36
  end
32
37
 
33
38
  config = get_config
@@ -51,10 +56,15 @@ if !find_library('uring', nil, File.join(liburing_path, 'src'))
51
56
  raise "Couldn't find liburing.a"
52
57
  end
53
58
 
54
- $defs << '-DHAVE_IORING_SETUP_SUBMIT_ALL' if config[:submit_all_flag]
55
- $defs << '-DHAVE_IORING_SETUP_COOP_TASKRUN' if config[:coop_taskrun_flag]
56
- $defs << '-DHAVE_IO_URING_PREP_BIND' if config[:prep_bind]
57
- $defs << '-DHAVE_IO_URING_PREP_LISTEN' if config[:prep_listen]
59
+ $defs << "-DUM_KERNEL_VERSION=#{config[:kernel_version]}"
60
+ $defs << '-DHAVE_IORING_SETUP_SUBMIT_ALL' if config[:submit_all_flag]
61
+ $defs << '-DHAVE_IORING_SETUP_COOP_TASKRUN' if config[:coop_taskrun_flag]
62
+ $defs << '-DHAVE_IO_URING_PREP_BIND' if config[:prep_bind]
63
+ $defs << '-DHAVE_IO_URING_PREP_LISTEN' if config[:prep_listen]
64
+ $defs << '-DHAVE_IO_URING_PREP_CMD_SOCK' if config[:prep_cmd_sock]
65
+ $defs << '-DHAVE_IO_URING_PREP_FUTEX' if config[:prep_futex]
66
+ $defs << '-DHAVE_IO_URING_PREP_WAITID' if config[:prep_waitid]
67
+ $defs << '-DHAVE_IO_URING_PREP_READ_MULTISHOT' if config[:prep_read_multishot]
58
68
  $CFLAGS << ' -Wno-pointer-arith'
59
69
 
60
70
  CONFIG['optflags'] << ' -fno-strict-aliasing'