polyphony 0.58 → 0.59
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/Gemfile.lock +1 -1
- data/ext/polyphony/backend_common.c +95 -4
- data/ext/polyphony/backend_common.h +23 -2
- data/ext/polyphony/backend_io_uring.c +67 -21
- data/ext/polyphony/backend_libev.c +63 -17
- data/ext/polyphony/fiber.c +0 -2
- data/ext/polyphony/polyphony.c +0 -7
- data/ext/polyphony/polyphony.h +6 -16
- data/ext/polyphony/polyphony_ext.c +0 -4
- data/ext/polyphony/runqueue.c +17 -82
- data/ext/polyphony/runqueue.h +27 -0
- data/ext/polyphony/thread.c +10 -99
- data/lib/polyphony/extensions/fiber.rb +2 -2
- data/lib/polyphony/extensions/thread.rb +1 -1
- data/lib/polyphony/version.rb +1 -1
- data/test/test_backend.rb +3 -3
- data/test/test_thread.rb +5 -11
- data/test/test_trace.rb +27 -49
- metadata +3 -4
- data/ext/polyphony/tracing.c +0 -11
- data/lib/polyphony/adapters/trace.rb +0 -138
@@ -262,7 +262,7 @@ module Polyphony
|
|
262
262
|
@parent = parent
|
263
263
|
@caller = caller
|
264
264
|
@block = block
|
265
|
-
|
265
|
+
Thread.backend.trace(:fiber_create, self)
|
266
266
|
schedule
|
267
267
|
end
|
268
268
|
|
@@ -311,7 +311,7 @@ module Polyphony
|
|
311
311
|
|
312
312
|
def finalize(result, uncaught_exception = false)
|
313
313
|
result, uncaught_exception = finalize_children(result, uncaught_exception)
|
314
|
-
|
314
|
+
Thread.backend.trace(:fiber_terminate, self, result)
|
315
315
|
@result = result
|
316
316
|
@running = false
|
317
317
|
inform_dependants(result, uncaught_exception)
|
data/lib/polyphony/version.rb
CHANGED
data/test/test_backend.rb
CHANGED
@@ -351,10 +351,10 @@ class BackendTest < MiniTest::Test
|
|
351
351
|
GC.enable
|
352
352
|
end
|
353
353
|
|
354
|
-
def
|
354
|
+
def test_idle_proc
|
355
355
|
counter = 0
|
356
356
|
|
357
|
-
@backend.
|
357
|
+
@backend.idle_proc = proc { counter += 1 }
|
358
358
|
|
359
359
|
3.times { snooze }
|
360
360
|
assert_equal 0, counter
|
@@ -368,7 +368,7 @@ class BackendTest < MiniTest::Test
|
|
368
368
|
3.times { snooze }
|
369
369
|
assert_equal 2, counter
|
370
370
|
|
371
|
-
@backend.
|
371
|
+
@backend.idle_proc = nil
|
372
372
|
sleep 0.01
|
373
373
|
assert_equal 2, counter
|
374
374
|
end
|
data/test/test_thread.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative 'helper'
|
4
|
-
require 'polyphony/adapters/trace'
|
5
4
|
|
6
5
|
class ThreadTest < MiniTest::Test
|
7
6
|
def test_thread_spin
|
@@ -130,18 +129,13 @@ class ThreadTest < MiniTest::Test
|
|
130
129
|
|
131
130
|
def test_that_suspend_returns_immediately_if_no_watchers
|
132
131
|
records = []
|
133
|
-
|
134
|
-
records << r if r[:event] =~ /^fiber_/
|
135
|
-
end
|
136
|
-
t.enable
|
137
|
-
Polyphony.trace(true)
|
138
|
-
|
132
|
+
Thread.backend.trace_proc = proc {|*r| records << r }
|
139
133
|
suspend
|
140
|
-
|
141
|
-
|
134
|
+
assert_equal [
|
135
|
+
[:fiber_switchpoint, Fiber.current]
|
136
|
+
], records
|
142
137
|
ensure
|
143
|
-
|
144
|
-
Polyphony.trace(false)
|
138
|
+
Thread.backend.trace_proc = nil
|
145
139
|
end
|
146
140
|
|
147
141
|
def test_thread_child_fiber_termination
|
data/test/test_trace.rb
CHANGED
@@ -1,70 +1,48 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative 'helper'
|
4
|
-
require 'polyphony/adapters/trace'
|
5
4
|
|
6
5
|
class TraceTest < MiniTest::Test
|
7
|
-
def test_tracing_disabled
|
8
|
-
records = []
|
9
|
-
t = Polyphony::Trace.new { |r| records << r if r[:event] =~ /^fiber_/ }
|
10
|
-
t.enable
|
11
|
-
snooze
|
12
|
-
assert_equal 0, records.size
|
13
|
-
ensure
|
14
|
-
t&.disable
|
15
|
-
Polyphony.trace(nil)
|
16
|
-
end
|
17
|
-
|
18
6
|
def test_tracing_enabled
|
19
|
-
|
20
|
-
|
21
|
-
Polyphony.trace(true)
|
22
|
-
t.enable
|
7
|
+
events = []
|
8
|
+
Thread.backend.trace_proc = proc { |*e| events << e }
|
23
9
|
snooze
|
24
|
-
t.disable
|
25
10
|
|
26
|
-
assert_equal
|
27
|
-
|
28
|
-
|
29
|
-
|
11
|
+
assert_equal [
|
12
|
+
[:fiber_schedule, Fiber.current, nil],
|
13
|
+
[:fiber_switchpoint, Fiber.current],
|
14
|
+
[:fiber_run, Fiber.current, nil]
|
15
|
+
], events
|
30
16
|
ensure
|
31
|
-
|
32
|
-
Polyphony.trace(nil)
|
17
|
+
Thread.backend.trace_proc = nil
|
33
18
|
end
|
34
19
|
|
35
20
|
def test_2_fiber_trace
|
36
|
-
|
37
|
-
|
38
|
-
t = Polyphony::Trace.new(:fiber_all) do |r|
|
39
|
-
records << r if Thread.current == thread && r[:event] =~ /^fiber_/
|
40
|
-
end
|
41
|
-
t.enable
|
42
|
-
Polyphony.trace(true)
|
21
|
+
events = []
|
22
|
+
Thread.backend.trace_proc = proc { |*e| events << e }
|
43
23
|
|
44
|
-
f = spin { sleep 0 }
|
24
|
+
f = spin { sleep 0; :byebye }
|
45
25
|
suspend
|
46
26
|
sleep 0
|
47
27
|
|
48
|
-
events = records.map { |r| [r[:fiber] == f ? :f : :current, r[:event]] }
|
49
28
|
assert_equal [
|
50
|
-
[:
|
51
|
-
[:f,
|
52
|
-
[:
|
53
|
-
[:f,
|
54
|
-
[:
|
55
|
-
[:
|
56
|
-
[:f,
|
57
|
-
[:
|
58
|
-
[:f,
|
59
|
-
[:f, :
|
60
|
-
[:
|
61
|
-
[:
|
62
|
-
[:current,
|
63
|
-
[:
|
64
|
-
[:current,
|
29
|
+
[:fiber_create, f],
|
30
|
+
[:fiber_schedule, f, nil],
|
31
|
+
[:fiber_switchpoint, Fiber.current],
|
32
|
+
[:fiber_run, f, nil],
|
33
|
+
[:fiber_switchpoint, f],
|
34
|
+
[:fiber_event_poll_enter, f],
|
35
|
+
[:fiber_schedule, f, nil],
|
36
|
+
[:fiber_event_poll_leave, f],
|
37
|
+
[:fiber_run, f, nil],
|
38
|
+
[:fiber_terminate, f, :byebye],
|
39
|
+
[:fiber_switchpoint, Fiber.current],
|
40
|
+
[:fiber_event_poll_enter, Fiber.current],
|
41
|
+
[:fiber_schedule, Fiber.current, nil],
|
42
|
+
[:fiber_event_poll_leave, Fiber.current],
|
43
|
+
[:fiber_run, Fiber.current, nil]
|
65
44
|
], events
|
66
45
|
ensure
|
67
|
-
|
68
|
-
Polyphony.trace(nil)
|
46
|
+
Thread.backend.trace_proc = nil
|
69
47
|
end
|
70
48
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: polyphony
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.59'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sharon Rosner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-06-
|
11
|
+
date: 2021-06-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake-compiler
|
@@ -437,11 +437,11 @@ files:
|
|
437
437
|
- ext/polyphony/ring_buffer.c
|
438
438
|
- ext/polyphony/ring_buffer.h
|
439
439
|
- ext/polyphony/runqueue.c
|
440
|
+
- ext/polyphony/runqueue.h
|
440
441
|
- ext/polyphony/runqueue_ring_buffer.c
|
441
442
|
- ext/polyphony/runqueue_ring_buffer.h
|
442
443
|
- ext/polyphony/socket_extensions.c
|
443
444
|
- ext/polyphony/thread.c
|
444
|
-
- ext/polyphony/tracing.c
|
445
445
|
- lib/polyphony.rb
|
446
446
|
- lib/polyphony/adapters/fs.rb
|
447
447
|
- lib/polyphony/adapters/irb.rb
|
@@ -451,7 +451,6 @@ files:
|
|
451
451
|
- lib/polyphony/adapters/readline.rb
|
452
452
|
- lib/polyphony/adapters/redis.rb
|
453
453
|
- lib/polyphony/adapters/sequel.rb
|
454
|
-
- lib/polyphony/adapters/trace.rb
|
455
454
|
- lib/polyphony/core/channel.rb
|
456
455
|
- lib/polyphony/core/exceptions.rb
|
457
456
|
- lib/polyphony/core/global_api.rb
|
data/ext/polyphony/tracing.c
DELETED
@@ -1,138 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative '../../polyphony'
|
4
|
-
|
5
|
-
STOCK_EVENTS = %i[line call return c_call c_return b_call b_return].freeze
|
6
|
-
|
7
|
-
module Polyphony
|
8
|
-
# Tracing functionality for Polyphony
|
9
|
-
module Trace
|
10
|
-
class << self
|
11
|
-
def new(*events)
|
12
|
-
start_stamp = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
|
13
|
-
events = STOCK_EVENTS if events.empty?
|
14
|
-
::TracePoint.new(*events) { |tp| yield trace_record(tp, start_stamp) }
|
15
|
-
end
|
16
|
-
|
17
|
-
def trace_record(trp, start_stamp)
|
18
|
-
stamp = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC) - start_stamp
|
19
|
-
|
20
|
-
{ stamp: stamp, event: trp.event, location: "#{trp.path}:#{trp.lineno}",
|
21
|
-
self: trp.self, binding: trp.binding, fiber: tp_fiber(trp),
|
22
|
-
lineno: trp.lineno, method_id: trp.method_id,
|
23
|
-
path: trp.path, parameters: tp_params(trp),
|
24
|
-
return_value: tp_return_value(trp), schedule_value: tp_schedule_value(trp),
|
25
|
-
exception: tp_raised_exception(trp) }
|
26
|
-
end
|
27
|
-
|
28
|
-
def tp_fiber(trp)
|
29
|
-
trp.is_a?(FiberTracePoint) ? trp.fiber : Fiber.current
|
30
|
-
end
|
31
|
-
|
32
|
-
PARAMS_EVENTS = %i[call c_call b_call].freeze
|
33
|
-
|
34
|
-
def tp_params(trp)
|
35
|
-
PARAMS_EVENTS.include?(trp.event) ? trp.parameters : nil
|
36
|
-
end
|
37
|
-
|
38
|
-
RETURN_VALUE_EVENTS = %i[return c_return b_return].freeze
|
39
|
-
|
40
|
-
def tp_return_value(trp)
|
41
|
-
RETURN_VALUE_EVENTS.include?(trp.event) ? trp.return_value : nil
|
42
|
-
end
|
43
|
-
|
44
|
-
SCHEDULE_VALUE_EVENTS = %i[fiber_schedule fiber_run].freeze
|
45
|
-
|
46
|
-
def tp_schedule_value(trp)
|
47
|
-
SCHEDULE_VALUE_EVENTS.include?(trp.event) ? trp.value : nil
|
48
|
-
end
|
49
|
-
|
50
|
-
def tp_raised_exception(trp)
|
51
|
-
trp.event == :raise && trp.raised_exception
|
52
|
-
end
|
53
|
-
|
54
|
-
def analyze(records)
|
55
|
-
by_fiber = Hash.new { |h, f| h[f] = [] }
|
56
|
-
records.each_with_object(by_fiber) { |r, h| h[r[:fiber]] << r }
|
57
|
-
{ by_fiber: by_fiber }
|
58
|
-
end
|
59
|
-
|
60
|
-
# Implements fake TracePoint instances for fiber-related events
|
61
|
-
class FiberTracePoint
|
62
|
-
attr_reader :event, :fiber, :value
|
63
|
-
|
64
|
-
def initialize(tpoint)
|
65
|
-
@tp = tpoint
|
66
|
-
@event = tpoint.return_value[0]
|
67
|
-
@fiber = tpoint.return_value[1]
|
68
|
-
@value = tpoint.return_value[2]
|
69
|
-
end
|
70
|
-
|
71
|
-
def lineno
|
72
|
-
@tp.lineno
|
73
|
-
end
|
74
|
-
|
75
|
-
def method_id
|
76
|
-
@tp.method_id
|
77
|
-
end
|
78
|
-
|
79
|
-
def path
|
80
|
-
@tp.path
|
81
|
-
end
|
82
|
-
|
83
|
-
def self
|
84
|
-
@tp.self
|
85
|
-
end
|
86
|
-
|
87
|
-
def binding
|
88
|
-
@tp.binding
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
class << ::TracePoint
|
93
|
-
POLYPHONY_FILE_REGEXP = /^#{::Exception::POLYPHONY_DIR}/.freeze
|
94
|
-
|
95
|
-
alias_method :orig_new, :new
|
96
|
-
def new(*args, &block)
|
97
|
-
events_mask, fiber_events_mask = event_masks(args)
|
98
|
-
|
99
|
-
orig_new(*events_mask) do |tp|
|
100
|
-
handle_tp_event(tp, fiber_events_mask, &block)
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
def handle_tp_event(tpoint, fiber_events_mask)
|
105
|
-
# next unless !$watched_fiber || Fiber.current == $watched_fiber
|
106
|
-
|
107
|
-
if tpoint.method_id == :__fiber_trace__
|
108
|
-
return if tpoint.event != :c_return
|
109
|
-
return unless fiber_events_mask.include?(tpoint.return_value[0])
|
110
|
-
|
111
|
-
tpoint = FiberTracePoint.new(tpoint)
|
112
|
-
elsif tpoint.path =~ POLYPHONY_FILE_REGEXP
|
113
|
-
return
|
114
|
-
end
|
115
|
-
|
116
|
-
yield tpoint
|
117
|
-
end
|
118
|
-
|
119
|
-
ALL_FIBER_EVENTS = %i[
|
120
|
-
fiber_create fiber_terminate fiber_schedule fiber_switchpoint fiber_run
|
121
|
-
fiber_event_poll_enter fiber_event_poll_leave
|
122
|
-
].freeze
|
123
|
-
|
124
|
-
def event_masks(events)
|
125
|
-
events.each_with_object([[], []]) do |e, masks|
|
126
|
-
case e
|
127
|
-
when /^fiber_/
|
128
|
-
masks[1] += e == :fiber_all ? ALL_FIBER_EVENTS : [e]
|
129
|
-
masks[0] << :c_return unless masks[0].include?(:c_return)
|
130
|
-
else
|
131
|
-
masks[0] << e
|
132
|
-
end
|
133
|
-
end
|
134
|
-
end
|
135
|
-
end
|
136
|
-
end
|
137
|
-
end
|
138
|
-
end
|