uringmachine 0.19.1 → 0.21.0

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 (97) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +3 -4
  3. data/CHANGELOG.md +32 -1
  4. data/TODO.md +0 -39
  5. data/examples/bm_fileno.rb +33 -0
  6. data/examples/bm_mutex.rb +85 -0
  7. data/examples/bm_mutex_single.rb +33 -0
  8. data/examples/bm_queue.rb +29 -29
  9. data/examples/bm_send.rb +2 -5
  10. data/examples/bm_snooze.rb +20 -42
  11. data/examples/bm_write.rb +4 -1
  12. data/examples/fiber_scheduler_demo.rb +15 -51
  13. data/examples/fiber_scheduler_fork.rb +24 -0
  14. data/examples/nc_ssl.rb +71 -0
  15. data/ext/um/extconf.rb +5 -15
  16. data/ext/um/um.c +310 -74
  17. data/ext/um/um.h +66 -29
  18. data/ext/um/um_async_op.c +1 -1
  19. data/ext/um/um_async_op_class.c +2 -2
  20. data/ext/um/um_buffer.c +1 -1
  21. data/ext/um/um_class.c +178 -31
  22. data/ext/um/um_const.c +51 -3
  23. data/ext/um/um_mutex_class.c +1 -1
  24. data/ext/um/um_op.c +37 -0
  25. data/ext/um/um_queue_class.c +1 -1
  26. data/ext/um/um_stream.c +5 -5
  27. data/ext/um/um_stream_class.c +3 -0
  28. data/ext/um/um_sync.c +28 -39
  29. data/ext/um/um_utils.c +59 -19
  30. data/grant-2025/journal.md +353 -0
  31. data/grant-2025/tasks.md +135 -0
  32. data/lib/uringmachine/fiber_scheduler.rb +316 -57
  33. data/lib/uringmachine/version.rb +1 -1
  34. data/lib/uringmachine.rb +6 -0
  35. data/test/test_fiber_scheduler.rb +640 -0
  36. data/test/test_stream.rb +2 -2
  37. data/test/test_um.rb +722 -54
  38. data/uringmachine.gemspec +5 -5
  39. data/vendor/liburing/.github/workflows/ci.yml +94 -1
  40. data/vendor/liburing/.github/workflows/test_build.c +9 -0
  41. data/vendor/liburing/configure +27 -0
  42. data/vendor/liburing/examples/Makefile +6 -0
  43. data/vendor/liburing/examples/helpers.c +8 -0
  44. data/vendor/liburing/examples/helpers.h +5 -0
  45. data/vendor/liburing/liburing.spec +1 -1
  46. data/vendor/liburing/src/Makefile +9 -3
  47. data/vendor/liburing/src/include/liburing/barrier.h +11 -5
  48. data/vendor/liburing/src/include/liburing/io_uring/query.h +41 -0
  49. data/vendor/liburing/src/include/liburing/io_uring.h +51 -0
  50. data/vendor/liburing/src/include/liburing/sanitize.h +16 -4
  51. data/vendor/liburing/src/include/liburing.h +458 -121
  52. data/vendor/liburing/src/liburing-ffi.map +16 -0
  53. data/vendor/liburing/src/liburing.map +8 -0
  54. data/vendor/liburing/src/sanitize.c +4 -1
  55. data/vendor/liburing/src/setup.c +7 -4
  56. data/vendor/liburing/test/232c93d07b74.c +4 -16
  57. data/vendor/liburing/test/Makefile +15 -1
  58. data/vendor/liburing/test/accept.c +2 -13
  59. data/vendor/liburing/test/bind-listen.c +175 -13
  60. data/vendor/liburing/test/conn-unreach.c +132 -0
  61. data/vendor/liburing/test/fd-pass.c +32 -7
  62. data/vendor/liburing/test/fdinfo.c +39 -12
  63. data/vendor/liburing/test/fifo-futex-poll.c +114 -0
  64. data/vendor/liburing/test/fifo-nonblock-read.c +1 -12
  65. data/vendor/liburing/test/futex.c +1 -1
  66. data/vendor/liburing/test/helpers.c +99 -2
  67. data/vendor/liburing/test/helpers.h +9 -0
  68. data/vendor/liburing/test/io_uring_passthrough.c +6 -12
  69. data/vendor/liburing/test/mock_file.c +379 -0
  70. data/vendor/liburing/test/mock_file.h +47 -0
  71. data/vendor/liburing/test/nop.c +2 -2
  72. data/vendor/liburing/test/nop32-overflow.c +150 -0
  73. data/vendor/liburing/test/nop32.c +126 -0
  74. data/vendor/liburing/test/pipe.c +166 -0
  75. data/vendor/liburing/test/poll-race-mshot.c +13 -1
  76. data/vendor/liburing/test/read-write.c +4 -4
  77. data/vendor/liburing/test/recv-mshot-fair.c +81 -34
  78. data/vendor/liburing/test/recvsend_bundle.c +1 -1
  79. data/vendor/liburing/test/resize-rings.c +2 -0
  80. data/vendor/liburing/test/ring-query.c +322 -0
  81. data/vendor/liburing/test/ringbuf-loop.c +87 -0
  82. data/vendor/liburing/test/ringbuf-read.c +4 -4
  83. data/vendor/liburing/test/runtests.sh +2 -2
  84. data/vendor/liburing/test/send-zerocopy.c +43 -5
  85. data/vendor/liburing/test/send_recv.c +103 -32
  86. data/vendor/liburing/test/shutdown.c +2 -12
  87. data/vendor/liburing/test/socket-nb.c +3 -14
  88. data/vendor/liburing/test/socket-rw-eagain.c +2 -12
  89. data/vendor/liburing/test/socket-rw-offset.c +2 -12
  90. data/vendor/liburing/test/socket-rw.c +2 -12
  91. data/vendor/liburing/test/sqe-mixed-bad-wrap.c +87 -0
  92. data/vendor/liburing/test/sqe-mixed-nop.c +82 -0
  93. data/vendor/liburing/test/sqe-mixed-uring_cmd.c +153 -0
  94. data/vendor/liburing/test/timestamp.c +56 -19
  95. data/vendor/liburing/test/vec-regbuf.c +2 -4
  96. data/vendor/liburing/test/wq-aff.c +7 -0
  97. metadata +37 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ff89f34d541e086f8016156d4b5290a6a2fdc94292f04e7a3104ef9e7cda256d
4
- data.tar.gz: 01dbe57b83effbab744fbd07461dcd803246a88bbf3ce1aeaf1e4eace32fd0ad
3
+ metadata.gz: e14941110d09a575728da68cb038a02334d151f0d384d88ad67a34b21a49d234
4
+ data.tar.gz: 158299106b117a973163ae480ea4e9827a0cb88eb76b2323da04fd631e8916ca
5
5
  SHA512:
6
- metadata.gz: ca0e44f1121384634b4234b2cd49643f87e8255e77eb250f64fb62be8bcdcb18e6a82480e5da003322c941c9ae2def119a048797d53bc064c4e1f77796b82c4d
7
- data.tar.gz: 322090fd12498525d303b63f66ec1c559ed9933e89e74d3b01c9cc5c0f3f1dcee951c767625690c288478d5e460248418bbd693fbd7c31146c7aff76cf545a5d
6
+ metadata.gz: f71a5b6b6740fea281df8880511b424a0c759e876e17f79a6b661453416d13c2d9d65e0c53ddee5df066ca92472571ffae8c0e9a4ca4fd745d02705a8645965d
7
+ data.tar.gz: baa86b9bc0009c69bfe894aae3489d43ed28d1fca44a24a9ddc7cc1625a54de6c17f65731c1a707af561942174f9584554a183a67f8428d5855e799c274db0b6
@@ -11,9 +11,8 @@ jobs:
11
11
  strategy:
12
12
  fail-fast: false
13
13
  matrix:
14
- # macos-latest uses arm64, macos-13 uses x86
15
14
  os: [ubuntu-latest]
16
- ruby: ['3.4', 'head']
15
+ ruby: ['head']
17
16
 
18
17
  name: ${{matrix.os}}, ${{matrix.ruby}}
19
18
 
@@ -32,5 +31,5 @@ jobs:
32
31
  - name: Compile C-extension
33
32
  run: bundle exec rake compile
34
33
  - name: Run tests
35
- # run: bundle exec ruby test/test_um.rb --name test_read_each_raising_2
36
- run: bundle exec rake test
34
+ run: bundle exec ruby test/run.rb --verbose
35
+ # run: bundle exec rake test
data/CHANGELOG.md CHANGED
@@ -1,4 +1,35 @@
1
- # 0.19.1 2025-01-03
1
+ # 0.21.0 2025-12-06
2
+
3
+ - Add `UM#submit`
4
+ - Update liburing
5
+ - Do not release GVL in um_submit if SQ does not need entering the kernel
6
+ - Fix compilation when rb_process_status_new is not available
7
+ - Fix um_futex_wake_transient to submit SQE, fix futex_wait usage
8
+ - Add debug logging for key io_uring interactions
9
+ - Add UM#mark and DEBUG_MARK for debugging specific UM instances
10
+ - Short-circuit zero-length writes
11
+ - Add optional file_offset argument to #read, #write. Add optional len and file_off
12
+ set arguments to #write_async
13
+ - Add support for specifying SQPOLL mode and SQ idle timeout in `UM#initialize`
14
+ - Add support for specifying number of SQ entries in `UM#initialize`
15
+ - Implement global worker pool for blocking operations in fiber scheduler
16
+ - Finish implementing all fiber scheduler hooks
17
+ - Add `UM#select`
18
+ - Add `UM#wakeup`
19
+ - Add `UM#total_op_count`
20
+
21
+ # 0.20.0 2025-11-26
22
+
23
+ - Add `UM.pidfd_open`, `UM.pidfd_send_signal` methods
24
+ - Add `#waitid`, `#waitid_status` methods, remove `#waitpid`
25
+ - Set minimal kernel version to 6.7
26
+ - Add `UM::Error` exception class
27
+ - Add support for `IO::Buffer` in all I/O methods
28
+ - Fix and improve mutex and queue implementations
29
+ - Add UM.debug method
30
+ - Implement Fiber scheduler (WIP)
31
+
32
+ # 0.19.1 2025-11-03
2
33
 
3
34
  - Add `RB_GC_GUARD` in `process_runqueue_op`
4
35
 
data/TODO.md CHANGED
@@ -1,44 +1,5 @@
1
1
  ## immediate
2
2
 
3
- - make a reproducer for segfault on timeout, spin lots of fibers where a timeout
4
- wraps a #shift call (from an empty queue).
5
- - see also: https://mensfeld.pl/2025/11/ruby-ffi-gc-bug-hash-becomes-string/
6
-
7
- Analysis:
8
-
9
- - The segfault is related to timeouts
10
- - Looking at process_runqueue_op (um.c):
11
-
12
- ```c
13
- inline VALUE process_runqueue_op(struct um *machine, struct um_op *op) {
14
- VALUE fiber = op->fiber;
15
- VALUE value = op->value;
16
-
17
- // on timeout, the op flags are changed to turn on OP_F_TRANSIENT
18
- if (unlikely(op->flags & OP_F_TRANSIENT))
19
- // here the op is freed, so the value is not visible to the GC anymoore
20
- um_op_free(machine, op);
21
-
22
- // if a GC occurs here, we risk a segfault
23
-
24
- // value is used
25
- return rb_fiber_transfer(fiber, 1, &value);
26
- }
27
- ```
28
-
29
- - So, a possible solution is to put a `RB_GC_GUARD` after the `return`.
30
- - But first, I want to be able to reproduce it. We can start by setting
31
- `GC.stress = true` on tests and see if we segfault.
32
-
33
- ## FiberScheduler implementation
34
-
35
- Some resources:
36
-
37
- - https://github.com/socketry/async/blob/main/context/getting-started.md
38
- - https://github.com/socketry/async/blob/main/context/scheduler.md
39
- - https://github.com/socketry/async/blob/main/lib/async/scheduler.rb#L28
40
- -
41
-
42
3
  ## useful concurrency tools
43
4
 
44
5
  - debounce
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/inline'
4
+
5
+ gemfile do
6
+ source 'https://rubygems.org'
7
+ gem 'benchmark'
8
+ gem 'benchmark-ips'
9
+ end
10
+
11
+ require 'benchmark/ips'
12
+
13
+ r, w = IO.pipe
14
+
15
+ class IO
16
+ def __fd__
17
+ @__fd__ ||= fileno
18
+ end
19
+ end
20
+
21
+ @map = ObjectSpace::WeakMap.new
22
+
23
+ def cached_fileno(r)
24
+ @map[r] ||= r.fileno
25
+ end
26
+
27
+ Benchmark.ips do |x|
28
+ x.report('IO#fileno') { r.fileno }
29
+ x.report('cached_fileno') { cached_fileno(r) }
30
+ x.report('__fd__') { r.__fd__ }
31
+
32
+ x.compare!(order: :baseline)
33
+ end
@@ -0,0 +1,85 @@
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
+ gem 'benchmark-ips'
10
+ end
11
+
12
+ require 'benchmark/ips'
13
+ require 'uringmachine'
14
+ require 'thread'
15
+
16
+ COUNT = 10
17
+ CONCURRENCY = (ENV['CONCURRENCY'] || 4).to_i
18
+
19
+ p(CONCURRENCY: CONCURRENCY)
20
+
21
+ STRING = "foo...bar"
22
+ REGEXP = /foo(.+)bar/
23
+
24
+ def threads_setup
25
+ @threads_mutex = Mutex.new
26
+ @threads_start = Queue.new
27
+ @threads_done = Queue.new
28
+ @threads = CONCURRENCY.times.map {
29
+ Thread.new do
30
+ loop do
31
+ @threads_start.shift
32
+ COUNT.times do
33
+ @threads_mutex.synchronize do
34
+ COUNT.times do
35
+ STRING.match(REGEXP)[1]
36
+ end
37
+ end
38
+ end
39
+ @threads_done << true
40
+ end
41
+ end
42
+ }
43
+ end
44
+
45
+ def threads_run
46
+ @threads_start << true
47
+ @threads_done.shift
48
+ end
49
+
50
+ def um_setup
51
+ @um_machine = UM.new
52
+ @um_mutex = UM::Mutex.new
53
+ @um_start = UM::Queue.new
54
+ @um_done = UM::Queue.new
55
+ @fibers = CONCURRENCY.times.map {
56
+ @um_machine.spin do
57
+ loop do
58
+ @um_machine.shift(@um_start)
59
+ COUNT.times do
60
+ @um_machine.synchronize(@um_mutex) do
61
+ COUNT.times do
62
+ STRING.match(REGEXP)[1]
63
+ end
64
+ end
65
+ end
66
+ @um_machine.push(@um_done, true)
67
+ end
68
+ end
69
+ }
70
+ end
71
+
72
+ def um_run
73
+ @um_machine.push(@um_start, true)
74
+ @um_machine.shift(@um_done)
75
+ end
76
+
77
+ threads_setup
78
+ um_setup
79
+
80
+ Benchmark.ips do |x|
81
+ x.report("threads") { @threads_run }
82
+ x.report("UM") { @um_run }
83
+
84
+ x.compare!(order: :baseline)
85
+ end
@@ -0,0 +1,33 @@
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
+ gem 'benchmark-ips'
10
+ end
11
+
12
+ require 'benchmark/ips'
13
+ require 'uringmachine'
14
+ require 'thread'
15
+
16
+ def threads_setup
17
+ @threads_mutex = Mutex.new
18
+ end
19
+
20
+ def um_setup
21
+ @um_machine = UM.new
22
+ @um_mutex = UM::Mutex.new
23
+ end
24
+
25
+ threads_setup
26
+ um_setup
27
+
28
+ Benchmark.ips do |x|
29
+ x.report("threads") { @threads_mutex.synchronize { } }
30
+ x.report("UM") { @um_machine.synchronize(@um_mutex) {} }
31
+
32
+ x.compare!(order: :baseline)
33
+ end
data/examples/bm_queue.rb CHANGED
@@ -5,24 +5,26 @@ require 'bundler/inline'
5
5
  gemfile do
6
6
  source 'https://rubygems.org'
7
7
  gem 'uringmachine', path: '..'
8
+ gem 'benchmark'
8
9
  gem 'benchmark-ips'
9
10
  end
10
11
 
11
12
  require 'benchmark/ips'
12
- require 'uringmachine'
13
+ require_relative '../lib/uringmachine'
13
14
 
14
15
  COUNT = 1000
15
- NUM_PRODUCERS = 2
16
- NUM_CONSUMERS = 10
16
+ NUM_PRODUCERS = 8
17
+ NUM_CONSUMERS = 8
18
+
19
+ @queue = Queue.new
20
+ @done = Queue.new
17
21
 
18
22
  def run_threads
19
- queue = Queue.new
20
- done = Queue.new
21
23
 
22
24
  NUM_PRODUCERS.times do
23
25
  Thread.new do
24
- COUNT.times { queue << rand(1000) }
25
- done << true
26
+ COUNT.times { @queue << rand(1000) }
27
+ @done << true
26
28
  end
27
29
  end
28
30
 
@@ -30,65 +32,64 @@ def run_threads
30
32
  NUM_CONSUMERS.times do
31
33
  Thread.new do
32
34
  loop do
33
- item = queue.shift
35
+ item = @queue.shift
34
36
  break if item.nil?
35
37
 
36
38
  total += item
37
39
  end
38
- done << true
40
+ @done << true
39
41
  end
40
42
  end
41
43
 
42
44
  # wait for producers
43
- NUM_PRODUCERS.times { done.shift }
45
+ NUM_PRODUCERS.times { @done.shift }
44
46
 
45
47
  # stop and wait for consumers
46
48
  NUM_CONSUMERS.times do
47
- queue << nil
48
- done.shift
49
+ @queue << nil
50
+ @done.shift
49
51
  end
50
52
 
51
53
  total
52
54
  end
53
55
 
54
- def run_um
55
- machine = UM.new
56
- queue = UM::Queue.new
57
- done = UM::Queue.new
56
+ @machine = UM.new
57
+ @um_queue = UM::Queue.new
58
+ @um_done = UM::Queue.new
58
59
 
60
+ def run_um
59
61
  NUM_PRODUCERS.times do
60
- machine.spin do
61
- COUNT.times { machine.push(queue, rand(1000)) }
62
- machine.push(done, true)
62
+ @machine.spin do
63
+ COUNT.times { @machine.push(@um_queue, rand(1000)) }
64
+ @machine.push(@um_done, true)
63
65
  end
64
66
  end
65
67
 
66
68
  total = 0
67
69
  NUM_CONSUMERS.times do
68
- machine.spin do
70
+ @machine.spin do
69
71
  loop do
70
- item = machine.shift(queue)
72
+ item = @machine.shift(@um_queue)
71
73
  break if item.nil?
72
74
 
73
75
  total += item
74
76
  end
75
- machine.push(done, true)
77
+ @machine.push(@um_done, true)
76
78
  end
77
79
  end
78
80
 
79
81
  # wait for producers
80
- NUM_PRODUCERS.times { machine.shift(done) }
82
+ NUM_PRODUCERS.times { @machine.shift(@um_done) }
81
83
 
82
84
  # stop and wait for consumers
83
85
  NUM_CONSUMERS.times do
84
- machine.push(queue, nil)
85
- machine.shift(done)
86
+ @machine.push(@um_queue, nil)
87
+ @machine.shift(@um_done)
86
88
  end
87
89
 
88
90
  total
89
91
  end
90
92
 
91
-
92
93
  # puts "running"
93
94
  # res = run_threads
94
95
  # p threads: res
@@ -98,14 +99,13 @@ end
98
99
  # p fibers: res
99
100
  # }
100
101
 
101
-
102
102
  # __END__
103
103
 
104
104
  Benchmark.ips do |x|
105
- x.config(:time => 5, :warmup => 2)
105
+ x.config(:time => 10, :warmup => 3)
106
106
 
107
107
  x.report("threads") { run_threads }
108
108
  x.report("UM") { run_um }
109
109
 
110
- x.compare!
110
+ x.compare!(order: :baseline)
111
111
  end
data/examples/bm_send.rb CHANGED
@@ -71,10 +71,6 @@ def um_send_bundle
71
71
  @machine.send_bundle(@server_fd, @bgid, @parts)
72
72
  end
73
73
 
74
- # um_send_bundle
75
- # 10.times { @machine.snooze }
76
- # exit
77
-
78
74
  p(STR_COUNT:, STR_SIZE:)
79
75
 
80
76
  Benchmark.ips do |x|
@@ -82,5 +78,6 @@ Benchmark.ips do |x|
82
78
  x.report('UM#write') { um_write }
83
79
  x.report('UM#send') { um_send }
84
80
  x.report('UM#send_bundle') { um_send_bundle }
85
- x.compare!
81
+
82
+ x.compare!(order: :baseline)
86
83
  end
@@ -15,37 +15,19 @@ ITERATIONS = 1000
15
15
 
16
16
  $machine = UringMachine.new
17
17
 
18
- def run_snooze
18
+ def run_snooze_um
19
19
  count = 0
20
- main = Fiber.current
21
20
 
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
21
+ f1 = $machine.spin {
22
+ ITERATIONS.times { count += 1; $machine.snooze }
23
+ }
24
+ f2 = $machine.spin {
25
+ ITERATIONS.times { count += 1; $machine.snooze }
26
+ }
33
27
 
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
28
+ $machine.join(f1, f2)
45
29
 
46
- $machine.schedule(f1, nil)
47
- $machine.schedule(f2, nil)
48
- $machine.yield
30
+ count
49
31
  end
50
32
 
51
33
  def run_raw_transfer
@@ -53,36 +35,32 @@ def run_raw_transfer
53
35
  main = Fiber.current
54
36
  f2 = nil
55
37
  f1 = Fiber.new do
56
- loop do
38
+ ITERATIONS.times do
57
39
  count += 1
58
- if count == ITERATIONS
59
- main.transfer(nil)
60
- break
61
- else
62
- f2.transfer(nil)
63
- end
40
+ f2.transfer(nil)
64
41
  end
65
42
  end
66
43
 
67
44
  f2 = Fiber.new do
68
- loop do
45
+ ITERATIONS.times do
69
46
  count += 1
70
- if count == ITERATIONS
71
- main.transfer(nil)
72
- break
73
- else
74
- f1.transfer(nil)
75
- end
47
+ f1.transfer(nil)
76
48
  end
49
+ main.transfer(nil)
77
50
  end
78
51
 
79
52
  f1.transfer(nil)
53
+
54
+ count
80
55
  end
81
56
 
57
+ p run_snooze_um: run_snooze_um
58
+ p run_raw_transfer: run_raw_transfer
59
+
82
60
  bm = Benchmark.ips do |x|
83
61
  x.config(:time => 5, :warmup => 2)
84
62
 
85
- x.report("snooze") { run_snooze }
63
+ x.report("snooze_um") { run_snooze_um }
86
64
  x.report("raw transfer") { run_raw_transfer }
87
65
 
88
66
  x.compare!
data/examples/bm_write.rb CHANGED
@@ -11,7 +11,7 @@ end
11
11
  require 'benchmark'
12
12
  require 'uringmachine'
13
13
 
14
- ITERATIONS = 100000
14
+ ITERATIONS = 10000
15
15
  BUF = ('*' * 8192).freeze
16
16
  FN = '/tmp/bm_write'
17
17
 
@@ -47,6 +47,9 @@ ensure
47
47
  fio.close
48
48
  end
49
49
 
50
+ run_io_write(1)
51
+ run_um_write(1)
52
+
50
53
  Benchmark.bm do |x|
51
54
  [1, 2, 4, 8].each do |c|
52
55
  x.report("IO (#{c} threads)") { run_io_write(c) }
@@ -1,71 +1,35 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../lib/uringmachine'
4
- require_relative '../lib/uringmachine/fiber_scheduler'
3
+ require 'bundler/setup'
4
+
5
+ require 'uringmachine'
6
+ require 'uringmachine/fiber_scheduler'
5
7
  require 'net/http'
6
8
 
7
- machine = UringMachine.new
8
- scheduler = UM::FiberScheduler.new(machine)
9
+ $machine = UringMachine.new
10
+ scheduler = UM::FiberScheduler.new($machine)
9
11
  Fiber.set_scheduler scheduler
10
12
 
11
13
  i, o = IO.pipe
12
14
 
13
15
  f1 = Fiber.schedule do
14
- # sleep 0.4
15
- # o.write 'Hello, world!'
16
- # o.close
16
+ puts "Hello from fiber 1!!!"
17
17
  end
18
18
 
19
19
  f2 = Fiber.schedule do
20
- # puts "hi"
21
- # 10.times do
22
- # sleep 0.1
23
- # puts "."
24
- # end
20
+ puts "Hello from fiber 2!!!"
25
21
  end
26
22
 
27
- # Fiber.schedule do
28
- # scheduler.block(:wait)
29
- # end
30
-
31
23
  f3 = Fiber.schedule do
32
- # message = i.read
33
- # puts message
34
- # rescue => e
35
- # scheduler.p e
36
- # scheduler.p e.backtrace
24
+ o.write 'hello'
25
+ puts "wrote it!"
26
+ o.close
37
27
  end
38
28
 
39
29
  f4 = Fiber.schedule do
40
- puts '*' * 40
41
- # tcp = TCPSocket.new('noteflakes.com', 80)
42
- # tcp.timeout = 10
43
- # scheduler.p tcp
44
- # tcp << "GET / HTTP/1.1\r\nHost: noteflakes.com\r\n\r\n"
45
- # s = tcp.read
46
- # scheduler.p s: s
47
- ret = Net::HTTP.get('noteflakes.com', '/ping')
48
- scheduler.p ret: ret
49
- rescue => e
50
- scheduler.p e
51
- scheduler.p e.backtrace
30
+ str = i.read
31
+ puts "got: #{str}"
52
32
  end
53
33
 
54
- scheduler.join(f1, f2, f3, f4)
55
-
56
- __END__
57
-
58
- stdout_fd = STDOUT.fileno
59
- stdin_fd = STDIN.fileno
60
- machine.write(stdout_fd, "Hello, world!\n")
61
-
62
- loop do
63
- machine.write(stdout_fd, "Say something: ")
64
- buf = +''
65
- res = machine.read(stdin_fd, buf, 8192)
66
- if res > 0
67
- machine.write(stdout_fd, "You said: #{buf}")
68
- else
69
- break
70
- end
71
- end
34
+ # scheduler.join
35
+ # Fiber.set_scheduler(nil)
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/setup'
4
+
5
+ require 'uringmachine'
6
+ require 'uringmachine/fiber_scheduler'
7
+ require 'net/http'
8
+
9
+ $machine = UringMachine.new
10
+ scheduler = UM::FiberScheduler.new($machine)
11
+ Fiber.set_scheduler scheduler
12
+
13
+ p parent: Fiber.scheduler
14
+ p Fiber.current
15
+
16
+ pid = fork do
17
+ Fiber.scheduler.post_fork
18
+ Fiber.set_scheduler nil
19
+ p child: Fiber.scheduler
20
+ # Fiber.scheduler.post_fork
21
+ end
22
+
23
+ Process.wait(pid)
24
+ p :done