polyphony 0.78 → 0.79

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 51eecc20956cb4f1a35a7f6510dea2730652700e99d29c7d42ade201a119ea2e
4
- data.tar.gz: bc2b57dc2cc5a8918bba1d8bf526cdbe23f44d134f9bdca5018b9e9e66930f91
3
+ metadata.gz: 34ed5a7685a8986f1fe5fd6cd714ee049633952746ecb8bced1aee73553c6c99
4
+ data.tar.gz: 03ded408e8849a921d0cfbbe1a232c5cea83cfbd58710efade4900f6240f511c
5
5
  SHA512:
6
- metadata.gz: 21c446f9a6fa032577b245e6de5155832c8e6932d6c17e58824a55923c82be014453b64b29ccbb66fe5d01cde8622d3275664acda403637954f1e7e6851e93c7
7
- data.tar.gz: a57831fe861ac51fa43692b66175291a457077822cdb5f795a093fca1e44bf95fb2b6a312cfe8a6c2b3c3e873319ffd03436e6236874a6acdd45843a21bc4981
6
+ metadata.gz: 91fe5a0979c0158315e942bba88f563a47926e78ad3da0ff8e483ee91aff1482af1f2fc3e3aa4cacd49e787531627bfc3295d45439e99d8400b4736b1a749443
7
+ data.tar.gz: 3c1eaaccec661c4f3e4c07853fbaaaab19222837d5ac25b4098856bd1b1367833cbc35a58602fb9c30ff8e7cd63d04f79206bf07438a1e842eb86871c8036063
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## 0.79 2022-02-19
2
+
3
+ - Overhaul trace events system (#73)
4
+
1
5
  ## 0.78 2022-02-16
2
6
 
3
7
  - Fix Polyphony::Queue API compatibility (#72)
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- polyphony (0.78)
4
+ polyphony (0.79)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -3,18 +3,21 @@
3
3
  require 'bundler/setup'
4
4
  require 'polyphony'
5
5
 
6
- pong = spin_loop do
6
+ require 'polyphony/core/debug'
7
+ Polyphony::Trace.start_event_firehose(STDOUT)
8
+
9
+ pong = spin_loop(:pong) do
7
10
  msg, ping = receive
8
11
  puts msg
9
12
  ping << 'pong'
10
13
  end
11
14
 
12
- ping = spin do
13
- 3.times do
15
+ ping = spin(:ping) do
16
+ 1.times do
14
17
  pong << ['ping', Fiber.current]
15
18
  msg = receive
16
19
  puts msg
17
20
  end
18
21
  end
19
22
 
20
- ping.await
23
+ ping.await
@@ -65,7 +65,7 @@ VALUE backend_base_switch_fiber(VALUE backend, struct Backend_base *base) {
65
65
 
66
66
  base->switch_count++;
67
67
  if (SHOULD_TRACE(base))
68
- TRACE(base, 3, SYM_fiber_switchpoint, current_fiber, CALLER());
68
+ TRACE(base, 3, SYM_block, current_fiber, CALLER());
69
69
 
70
70
  while (1) {
71
71
  next = runqueue_shift(&base->runqueue);
@@ -96,8 +96,6 @@ VALUE backend_base_switch_fiber(VALUE backend, struct Backend_base *base) {
96
96
  if (next.fiber == Qnil) return Qnil;
97
97
 
98
98
  // run next fiber
99
- COND_TRACE(base, 3, SYM_fiber_run, next.fiber, next.value);
100
-
101
99
  rb_ivar_set(next.fiber, ID_ivar_runnable, Qnil);
102
100
  RB_GC_GUARD(next.fiber);
103
101
  RB_GC_GUARD(next.value);
@@ -112,7 +110,7 @@ void backend_base_schedule_fiber(VALUE thread, VALUE backend, struct Backend_bas
112
110
  if (rb_fiber_alive_p(fiber) != Qtrue) return;
113
111
  already_runnable = rb_ivar_get(fiber, ID_ivar_runnable) != Qnil;
114
112
 
115
- COND_TRACE(base, 4, SYM_fiber_schedule, fiber, value, prioritize ? Qtrue : Qfalse);
113
+ COND_TRACE(base, 5, SYM_schedule, fiber, value, prioritize ? Qtrue : Qfalse, CALLER());
116
114
 
117
115
  runqueue = rb_ivar_get(fiber, ID_ivar_parked) == Qtrue ? &base->parked_runqueue : &base->runqueue;
118
116
 
@@ -244,15 +242,24 @@ inline VALUE backend_await(struct Backend_base *backend) {
244
242
  VALUE ret;
245
243
  backend->pending_count++;
246
244
  ret = Thread_switch_fiber(rb_thread_current());
245
+
246
+ // run next fiber
247
+ COND_TRACE(backend, 4, SYM_unblock, rb_fiber_current(), ret, CALLER());
248
+
247
249
  backend->pending_count--;
248
250
  RB_GC_GUARD(ret);
249
251
  return ret;
250
252
  }
251
253
 
252
- inline VALUE backend_snooze() {
254
+ inline VALUE backend_snooze(struct Backend_base *backend) {
253
255
  VALUE ret;
254
- Fiber_make_runnable(rb_fiber_current(), Qnil);
255
- ret = Thread_switch_fiber(rb_thread_current());
256
+ VALUE fiber = rb_fiber_current();
257
+ VALUE thread = rb_thread_current();
258
+ Fiber_make_runnable(fiber, Qnil);
259
+ ret = Thread_switch_fiber(thread);
260
+
261
+ COND_TRACE(backend, 4, SYM_unblock, fiber, ret, CALLER());
262
+
256
263
  return ret;
257
264
  }
258
265
 
@@ -80,7 +80,7 @@ void fptr_finalize(rb_io_t *fptr);
80
80
 
81
81
  struct backend_stats backend_get_stats(VALUE self);
82
82
  VALUE backend_await(struct Backend_base *backend);
83
- VALUE backend_snooze();
83
+ VALUE backend_snooze(struct Backend_base *backend);
84
84
 
85
85
  // macros for doing read loops
86
86
  #define READ_LOOP_PREPARE_STR() { \
@@ -216,12 +216,12 @@ inline VALUE Backend_poll(VALUE self, VALUE blocking) {
216
216
  io_uring_submit(&backend->ring);
217
217
  }
218
218
 
219
- COND_TRACE(&backend->base, 2, SYM_fiber_event_poll_enter, rb_fiber_current());
219
+ COND_TRACE(&backend->base, 2, SYM_enter_poll, rb_fiber_current());
220
220
 
221
221
  if (is_blocking) io_uring_backend_poll(backend);
222
222
  io_uring_backend_handle_ready_cqes(backend);
223
223
 
224
- COND_TRACE(&backend->base, 2, SYM_fiber_event_poll_leave, rb_fiber_current());
224
+ COND_TRACE(&backend->base, 2, SYM_leave_poll, rb_fiber_current());
225
225
 
226
226
  return self;
227
227
  }
@@ -1108,7 +1108,7 @@ VALUE Backend_timer_loop(VALUE self, VALUE interval) {
1108
1108
  if (!completed) return resume_value;
1109
1109
  }
1110
1110
  else {
1111
- resume_value = backend_snooze();
1111
+ resume_value = backend_snooze(&backend->base);
1112
1112
  RAISE_IF_EXCEPTION(resume_value);
1113
1113
  }
1114
1114
 
@@ -1591,6 +1591,22 @@ VALUE Backend_trace_proc_set(VALUE self, VALUE block) {
1591
1591
  return self;
1592
1592
  }
1593
1593
 
1594
+ VALUE Backend_snooze(VALUE self) {
1595
+ VALUE ret;
1596
+ VALUE fiber = rb_fiber_current();
1597
+ Backend_t *backend;
1598
+ GetBackend(self, backend);
1599
+
1600
+ Fiber_make_runnable(fiber, Qnil);
1601
+ ret = Thread_switch_fiber(rb_thread_current());
1602
+
1603
+ COND_TRACE(&backend->base, 4, SYM_unblock, rb_fiber_current(), ret, CALLER());
1604
+
1605
+ RAISE_IF_EXCEPTION(ret);
1606
+ RB_GC_GUARD(ret);
1607
+ return ret;
1608
+ }
1609
+
1594
1610
  void Backend_park_fiber(VALUE self, VALUE fiber) {
1595
1611
  Backend_t *backend;
1596
1612
  GetBackend(self, backend);
@@ -168,7 +168,7 @@ inline VALUE Backend_poll(VALUE self, VALUE blocking) {
168
168
 
169
169
  backend->base.poll_count++;
170
170
 
171
- COND_TRACE(&backend->base, 2, SYM_fiber_event_poll_enter, rb_fiber_current());
171
+ COND_TRACE(&backend->base, 2, SYM_enter_poll, rb_fiber_current());
172
172
 
173
173
  ev_run:
174
174
  backend->base.currently_polling = 1;
@@ -177,7 +177,7 @@ ev_run:
177
177
  backend->base.currently_polling = 0;
178
178
  if (errno == EINTR && runqueue_empty_p(&backend->base.runqueue)) goto ev_run;
179
179
 
180
- COND_TRACE(&backend->base, 2, SYM_fiber_event_poll_leave, rb_fiber_current());
180
+ COND_TRACE(&backend->base, 2, SYM_leave_poll, rb_fiber_current());
181
181
 
182
182
  return self;
183
183
  }
@@ -305,7 +305,7 @@ VALUE Backend_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eof,
305
305
  if (TEST_EXCEPTION(switchpoint_result)) goto error;
306
306
  }
307
307
  else {
308
- switchpoint_result = backend_snooze();
308
+ switchpoint_result = backend_snooze(&backend->base);
309
309
  if (TEST_EXCEPTION(switchpoint_result)) goto error;
310
310
 
311
311
  if (n == 0) break; // EOF
@@ -375,7 +375,7 @@ VALUE Backend_read_loop(VALUE self, VALUE io, VALUE maxlen) {
375
375
  if (TEST_EXCEPTION(switchpoint_result)) goto error;
376
376
  }
377
377
  else {
378
- switchpoint_result = backend_snooze();
378
+ switchpoint_result = backend_snooze(&backend->base);
379
379
 
380
380
  if (TEST_EXCEPTION(switchpoint_result)) goto error;
381
381
 
@@ -428,7 +428,7 @@ VALUE Backend_feed_loop(VALUE self, VALUE io, VALUE receiver, VALUE method) {
428
428
  if (TEST_EXCEPTION(switchpoint_result)) goto error;
429
429
  }
430
430
  else {
431
- switchpoint_result = backend_snooze();
431
+ switchpoint_result = backend_snooze(&backend->base);
432
432
 
433
433
  if (TEST_EXCEPTION(switchpoint_result)) goto error;
434
434
 
@@ -483,7 +483,7 @@ VALUE Backend_write(VALUE self, VALUE io, VALUE str) {
483
483
  }
484
484
 
485
485
  if (watcher.fiber == Qnil) {
486
- switchpoint_result = backend_snooze();
486
+ switchpoint_result = backend_snooze(&backend->base);
487
487
 
488
488
  if (TEST_EXCEPTION(switchpoint_result)) goto error;
489
489
  }
@@ -558,7 +558,7 @@ VALUE Backend_writev(VALUE self, VALUE io, int argc, VALUE *argv) {
558
558
  }
559
559
  }
560
560
  if (watcher.fiber == Qnil) {
561
- switchpoint_result = backend_snooze();
561
+ switchpoint_result = backend_snooze(&backend->base);
562
562
  if (TEST_EXCEPTION(switchpoint_result)) goto error;
563
563
  }
564
564
 
@@ -611,7 +611,7 @@ VALUE Backend_accept(VALUE self, VALUE server_socket, VALUE socket_class) {
611
611
  else {
612
612
  VALUE socket;
613
613
  rb_io_t *fp;
614
- switchpoint_result = backend_snooze();
614
+ switchpoint_result = backend_snooze(&backend->base);
615
615
 
616
616
  if (TEST_EXCEPTION(switchpoint_result)) {
617
617
  close(fd); // close fd since we're raising an exception
@@ -669,7 +669,7 @@ VALUE Backend_accept_loop(VALUE self, VALUE server_socket, VALUE socket_class) {
669
669
  }
670
670
  else {
671
671
  rb_io_t *fp;
672
- switchpoint_result = backend_snooze();
672
+ switchpoint_result = backend_snooze(&backend->base);
673
673
 
674
674
  if (TEST_EXCEPTION(switchpoint_result)) {
675
675
  close(fd); // close fd since we're raising an exception
@@ -727,7 +727,7 @@ VALUE Backend_connect(VALUE self, VALUE sock, VALUE host, VALUE port) {
727
727
  if (TEST_EXCEPTION(switchpoint_result)) goto error;
728
728
  }
729
729
  else {
730
- switchpoint_result = backend_snooze();
730
+ switchpoint_result = backend_snooze(&backend->base);
731
731
 
732
732
  if (TEST_EXCEPTION(switchpoint_result)) goto error;
733
733
  }
@@ -774,7 +774,7 @@ VALUE Backend_send(VALUE self, VALUE io, VALUE str, VALUE flags) {
774
774
  }
775
775
 
776
776
  if (watcher.fiber == Qnil) {
777
- switchpoint_result = backend_snooze();
777
+ switchpoint_result = backend_snooze(&backend->base);
778
778
 
779
779
  if (TEST_EXCEPTION(switchpoint_result)) goto error;
780
780
  }
@@ -880,7 +880,7 @@ VALUE Backend_splice(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
880
880
  }
881
881
 
882
882
  if (watcher.ctx.fiber == Qnil) {
883
- switchpoint_result = backend_snooze();
883
+ switchpoint_result = backend_snooze(&backend->base);
884
884
  if (TEST_EXCEPTION(switchpoint_result)) goto error;
885
885
  }
886
886
 
@@ -935,7 +935,7 @@ VALUE Backend_splice_to_eof(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
935
935
  }
936
936
 
937
937
  if (watcher.ctx.fiber == Qnil) {
938
- switchpoint_result = backend_snooze();
938
+ switchpoint_result = backend_snooze(&backend->base);
939
939
  if (TEST_EXCEPTION(switchpoint_result)) goto error;
940
940
  }
941
941
 
@@ -1009,7 +1009,7 @@ VALUE Backend_splice(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
1009
1009
  }
1010
1010
 
1011
1011
  if (watcher.fiber == Qnil) {
1012
- switchpoint_result = backend_snooze();
1012
+ switchpoint_result = backend_snooze(&backend->base);
1013
1013
  if (TEST_EXCEPTION(switchpoint_result)) goto error;
1014
1014
  }
1015
1015
 
@@ -1089,7 +1089,7 @@ VALUE Backend_splice_to_eof(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
1089
1089
 
1090
1090
  done:
1091
1091
  if (watcher.fiber == Qnil) {
1092
- switchpoint_result = backend_snooze();
1092
+ switchpoint_result = backend_snooze(&backend->base);
1093
1093
  if (TEST_EXCEPTION(switchpoint_result)) goto error;
1094
1094
  }
1095
1095
 
@@ -1171,7 +1171,7 @@ noreturn VALUE Backend_timer_loop(VALUE self, VALUE interval) {
1171
1171
  RAISE_IF_EXCEPTION(resume_value);
1172
1172
  }
1173
1173
  else {
1174
- resume_value = backend_snooze();
1174
+ resume_value = backend_snooze(&backend->base);
1175
1175
  RAISE_IF_EXCEPTION(resume_value);
1176
1176
  }
1177
1177
 
@@ -1530,7 +1530,7 @@ VALUE Backend_splice_chunks(VALUE self, VALUE src, VALUE dest, VALUE prefix, VAL
1530
1530
  }
1531
1531
 
1532
1532
  if (watcher.ctx.fiber == Qnil) {
1533
- result = backend_snooze();
1533
+ result = backend_snooze(&backend->base);
1534
1534
  if (TEST_EXCEPTION(result)) goto error;
1535
1535
  }
1536
1536
  RB_GC_GUARD(str);
@@ -1564,6 +1564,22 @@ VALUE Backend_trace_proc_set(VALUE self, VALUE block) {
1564
1564
  return self;
1565
1565
  }
1566
1566
 
1567
+ VALUE Backend_snooze(VALUE self) {
1568
+ VALUE ret;
1569
+ VALUE fiber = rb_fiber_current();
1570
+ Backend_t *backend;
1571
+ GetBackend(self, backend);
1572
+
1573
+ Fiber_make_runnable(fiber, Qnil);
1574
+ ret = Thread_switch_fiber(rb_thread_current());
1575
+
1576
+ COND_TRACE(&backend->base, 4, SYM_unblock, rb_fiber_current(), ret, CALLER());
1577
+
1578
+ RAISE_IF_EXCEPTION(ret);
1579
+ RB_GC_GUARD(ret);
1580
+ return ret;
1581
+ }
1582
+
1567
1583
  void Backend_park_fiber(VALUE self, VALUE fiber) {
1568
1584
  Backend_t *backend;
1569
1585
  GetBackend(self, backend);
@@ -10,13 +10,13 @@ VALUE SYM_running;
10
10
  VALUE SYM_runnable;
11
11
  VALUE SYM_waiting;
12
12
 
13
- VALUE SYM_fiber_create;
14
- VALUE SYM_fiber_event_poll_enter;
15
- VALUE SYM_fiber_event_poll_leave;
16
- VALUE SYM_fiber_run;
17
- VALUE SYM_fiber_schedule;
18
- VALUE SYM_fiber_switchpoint;
19
- VALUE SYM_fiber_terminate;
13
+ VALUE SYM_spin;
14
+ VALUE SYM_enter_poll;
15
+ VALUE SYM_leave_poll;
16
+ VALUE SYM_unblock;
17
+ VALUE SYM_schedule;
18
+ VALUE SYM_block;
19
+ VALUE SYM_terminate;
20
20
 
21
21
  static VALUE Fiber_safe_transfer(int argc, VALUE *argv, VALUE self) {
22
22
  VALUE arg = (argc == 0) ? Qnil : argv[0];
@@ -157,24 +157,24 @@ void Init_Fiber() {
157
157
  rb_global_variable(&SYM_runnable);
158
158
  rb_global_variable(&SYM_waiting);
159
159
 
160
- ID_ivar_auto_watcher = rb_intern("@auto_watcher");
161
- ID_ivar_mailbox = rb_intern("@mailbox");
162
- ID_ivar_result = rb_intern("@result");
163
- ID_ivar_waiting_fibers = rb_intern("@waiting_fibers");
164
-
165
- SYM_fiber_create = ID2SYM(rb_intern("fiber_create"));
166
- SYM_fiber_event_poll_enter = ID2SYM(rb_intern("fiber_event_poll_enter"));
167
- SYM_fiber_event_poll_leave = ID2SYM(rb_intern("fiber_event_poll_leave"));
168
- SYM_fiber_run = ID2SYM(rb_intern("fiber_run"));
169
- SYM_fiber_schedule = ID2SYM(rb_intern("fiber_schedule"));
170
- SYM_fiber_switchpoint = ID2SYM(rb_intern("fiber_switchpoint"));
171
- SYM_fiber_terminate = ID2SYM(rb_intern("fiber_terminate"));
172
-
173
- rb_global_variable(&SYM_fiber_create);
174
- rb_global_variable(&SYM_fiber_event_poll_enter);
175
- rb_global_variable(&SYM_fiber_event_poll_leave);
176
- rb_global_variable(&SYM_fiber_run);
177
- rb_global_variable(&SYM_fiber_schedule);
178
- rb_global_variable(&SYM_fiber_switchpoint);
179
- rb_global_variable(&SYM_fiber_terminate);
160
+ ID_ivar_auto_watcher = rb_intern("@auto_watcher");
161
+ ID_ivar_mailbox = rb_intern("@mailbox");
162
+ ID_ivar_result = rb_intern("@result");
163
+ ID_ivar_waiting_fibers = rb_intern("@waiting_fibers");
164
+
165
+ SYM_spin = ID2SYM(rb_intern("spin"));
166
+ SYM_enter_poll = ID2SYM(rb_intern("enter_poll"));
167
+ SYM_leave_poll = ID2SYM(rb_intern("leave_poll"));
168
+ SYM_unblock = ID2SYM(rb_intern("unblock"));
169
+ SYM_schedule = ID2SYM(rb_intern("schedule"));
170
+ SYM_block = ID2SYM(rb_intern("block"));
171
+ SYM_terminate = ID2SYM(rb_intern("terminate"));
172
+
173
+ rb_global_variable(&SYM_spin);
174
+ rb_global_variable(&SYM_enter_poll);
175
+ rb_global_variable(&SYM_leave_poll);
176
+ rb_global_variable(&SYM_unblock);
177
+ rb_global_variable(&SYM_schedule);
178
+ rb_global_variable(&SYM_block);
179
+ rb_global_variable(&SYM_terminate);
180
180
  }
@@ -27,14 +27,7 @@ ID ID_W;
27
27
  ID ID_RW;
28
28
 
29
29
  VALUE Polyphony_snooze(VALUE self) {
30
- VALUE ret;
31
- VALUE fiber = rb_fiber_current();
32
-
33
- Fiber_make_runnable(fiber, Qnil);
34
- ret = Thread_switch_fiber(rb_thread_current());
35
- RAISE_IF_EXCEPTION(ret);
36
- RB_GC_GUARD(ret);
37
- return ret;
30
+ return Backend_snooze(BACKEND());
38
31
  }
39
32
 
40
33
  static VALUE Polyphony_suspend(VALUE self) {
@@ -61,13 +61,13 @@ extern ID ID_switch_fiber;
61
61
  extern ID ID_to_s;
62
62
  extern ID ID_transfer;
63
63
 
64
- extern VALUE SYM_fiber_create;
65
- extern VALUE SYM_fiber_event_poll_enter;
66
- extern VALUE SYM_fiber_event_poll_leave;
67
- extern VALUE SYM_fiber_run;
68
- extern VALUE SYM_fiber_schedule;
69
- extern VALUE SYM_fiber_switchpoint;
70
- extern VALUE SYM_fiber_terminate;
64
+ extern VALUE SYM_spin;
65
+ extern VALUE SYM_enter_poll;
66
+ extern VALUE SYM_leave_poll;
67
+ extern VALUE SYM_unblock;
68
+ extern VALUE SYM_schedule;
69
+ extern VALUE SYM_block;
70
+ extern VALUE SYM_terminate;
71
71
 
72
72
  VALUE Fiber_auto_watcher(VALUE self);
73
73
  void Fiber_make_runnable(VALUE fiber, VALUE value);
@@ -121,11 +121,14 @@ VALUE Backend_wait_event(VALUE self, VALUE raise_on_exception);
121
121
  VALUE Backend_wakeup(VALUE self);
122
122
  VALUE Backend_run_idle_tasks(VALUE self);
123
123
  VALUE Backend_switch_fiber(VALUE self);
124
+
124
125
  void Backend_schedule_fiber(VALUE thread, VALUE self, VALUE fiber, VALUE value, int prioritize);
125
126
  void Backend_unschedule_fiber(VALUE self, VALUE fiber);
126
127
  void Backend_park_fiber(VALUE self, VALUE fiber);
127
128
  void Backend_unpark_fiber(VALUE self, VALUE fiber);
128
129
 
130
+ VALUE Backend_snooze(VALUE self);
131
+
129
132
  void Thread_schedule_fiber(VALUE thread, VALUE fiber, VALUE value);
130
133
  void Thread_schedule_fiber_with_priority(VALUE thread, VALUE fiber, VALUE value);
131
134
  VALUE Thread_switch_fiber(VALUE thread);
@@ -23,11 +23,15 @@ VALUE Thread_fiber_unschedule(VALUE self, VALUE fiber) {
23
23
  }
24
24
 
25
25
  inline void Thread_schedule_fiber(VALUE self, VALUE fiber, VALUE value) {
26
- schedule_fiber(self, fiber, value, 0);
26
+ Backend_schedule_fiber(self, rb_ivar_get(self, ID_ivar_backend), fiber, value, 0);
27
+
28
+ // schedule_fiber(self, fiber, value, 0);
27
29
  }
28
30
 
29
31
  inline void Thread_schedule_fiber_with_priority(VALUE self, VALUE fiber, VALUE value) {
30
- schedule_fiber(self, fiber, value, 1);
32
+ Backend_schedule_fiber(self, rb_ivar_get(self, ID_ivar_backend), fiber, value, 1);
33
+
34
+ // schedule_fiber(self, fiber, value, 1);
31
35
  }
32
36
 
33
37
  VALUE Thread_switch_fiber(VALUE self) {
@@ -13,3 +13,147 @@ module ::Kernel
13
13
  end
14
14
  end
15
15
  end
16
+
17
+ module Polyphony
18
+ module Trace
19
+ class << self
20
+ def start_event_firehose(io = nil, &block)
21
+ Thread.backend.trace_proc = firehose_proc(io, block)
22
+ end
23
+
24
+ private
25
+
26
+ def firehose_proc(io, block)
27
+ if io
28
+ ->(*e) { io.orig_write("#{trace_event_info(e).inspect}\n") }
29
+ elsif block
30
+ ->(*e) { block.(trace_event_info(e)) }
31
+ else
32
+ raise "Please provide an io or a block"
33
+ end
34
+ end
35
+
36
+ def trace_event_info(e)
37
+ {
38
+ stamp: format_current_time,
39
+ event: e[0]
40
+ }.merge(
41
+ send(:"event_props_#{e[0]}", e)
42
+ )
43
+ end
44
+
45
+ def format_trace_event_message(e)
46
+ props = send(:"event_props_#{e[0]}", e).merge(
47
+ timestamp: format_current_time,
48
+ event: e[0]
49
+ )
50
+ # templ = send(:"event_format_#{e[0]}", e)
51
+
52
+ # msg = format("%<timestamp>s #{templ}\n", **props)
53
+ end
54
+
55
+ def format_current_time
56
+ Time.now.strftime('%Y-%m-%d %H:%M:%S')
57
+ end
58
+
59
+ def generic_event_format
60
+ '%<event>-12.12s'
61
+ end
62
+
63
+ def fiber_event_format
64
+ "#{generic_event_format} %<fiber>-44.44s"
65
+ end
66
+
67
+ def event_props_enter_poll(e)
68
+ {}
69
+ end
70
+
71
+ def event_format_enter_poll(e)
72
+ generic_event_format
73
+ end
74
+
75
+ def event_props_leave_poll(e)
76
+ {}
77
+ end
78
+
79
+ def event_format_leave_poll(e)
80
+ generic_event_format
81
+ end
82
+
83
+ def event_props_schedule(e)
84
+ {
85
+ fiber: e[1],
86
+ value: e[2],
87
+ caller: e[4],
88
+ source_fiber: Fiber.current
89
+ }
90
+ end
91
+
92
+ def event_format_schedule(e)
93
+ "#{fiber_event_format} %<value>-24.24p %<caller>-120.120s <= %<origin_fiber>s"
94
+ end
95
+
96
+ def event_props_unblock(e)
97
+ {
98
+ fiber: e[1],
99
+ value: e[2],
100
+ caller: e[3],
101
+ }
102
+ end
103
+
104
+ def event_format_unblock(e)
105
+ "#{fiber_event_format} %<value>-24.24p %<caller>-120.120s"
106
+ end
107
+
108
+ def event_props_terminate(e)
109
+ {
110
+ fiber: e[1],
111
+ value: e[2],
112
+ }
113
+ end
114
+
115
+ def event_format_terminate(e)
116
+ "#{fiber_event_format} %<value>-24.24p"
117
+ end
118
+
119
+ def event_props_block(e)
120
+ {
121
+ fiber: e[1],
122
+ caller: e[2]
123
+ }
124
+ end
125
+
126
+ def event_format_block(e)
127
+ "#{fiber_event_format} #{' ' * 24} %<caller>-120.120s"
128
+ end
129
+
130
+ def event_props_spin(e)
131
+ {
132
+ fiber: e[1],
133
+ caller: e[2],
134
+ source_fiber: Fiber.current
135
+ }
136
+ end
137
+
138
+ def event_format_spin(e)
139
+ "#{fiber_event_format} #{' ' * 24} %<caller>-120.120s <= %<origin_fiber>s"
140
+ end
141
+
142
+ def fibe_repr(fiber)
143
+ format("%-6x %-20.20s %-10.10s", fiber.object_id, fiber.tag, "(#{fiber.state})")
144
+ end
145
+
146
+ def fiber_compact_repr(fiber)
147
+ if fiber.tag
148
+ format("%-6x %-.20s %-.10s", fiber.object_id, fiber.tag, "(#{fiber.state})")
149
+ else
150
+ format("%-6x %-.10s", fiber.object_id, "(#{fiber.state})")
151
+ end
152
+ end
153
+
154
+ def caller_repr(c)
155
+ c.map { |i| i.gsub('/home/sharon/repo/polyphony/lib/polyphony', '') }.join(' ')
156
+ end
157
+ end
158
+ end
159
+ end
@@ -250,16 +250,17 @@ module Polyphony
250
250
  def schedule_priority_oob_fiber(&block)
251
251
  oob_fiber = Fiber.new do
252
252
  Fiber.current.setup_raw
253
+ Thread.backend.trace(:unblock, oob_fiber, nil, @caller)
253
254
  result = block.call
254
255
  rescue Exception => e
255
256
  Thread.current.schedule_and_wakeup(Thread.main.main_fiber, e)
256
257
  result = e
257
258
  ensure
258
- Thread.backend.trace(:fiber_terminate, Fiber.current, result)
259
+ Thread.backend.trace(:terminate, Fiber.current, result)
259
260
  suspend
260
261
  end
261
262
  prepare_oob_fiber(oob_fiber, block)
262
- Thread.backend.trace(:fiber_create, oob_fiber)
263
+ Thread.backend.trace(:spin, oob_fiber, caller)
263
264
  oob_fiber.schedule_with_priority(nil)
264
265
  end
265
266
 
@@ -355,12 +356,13 @@ module Polyphony
355
356
  @parent = parent
356
357
  @caller = caller
357
358
  @block = block
358
- Thread.backend.trace(:fiber_create, self)
359
+ Thread.backend.trace(:spin, self, Kernel.caller[1..-1])
359
360
  schedule
360
361
  end
361
362
 
362
363
  def run(first_value)
363
364
  setup first_value
365
+ Thread.backend.trace(:unblock, self, first_value, @caller)
364
366
  result = @block.(first_value)
365
367
  finalize result
366
368
  rescue Polyphony::Restart => e
@@ -402,7 +404,7 @@ module Polyphony
402
404
 
403
405
  def finalize(result, uncaught_exception = false)
404
406
  result, uncaught_exception = finalize_children(result, uncaught_exception)
405
- Thread.backend.trace(:fiber_terminate, self, result)
407
+ Thread.backend.trace(:terminate, self, result)
406
408
  @result = result
407
409
 
408
410
  inform_monitors(result, uncaught_exception)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Polyphony
4
- VERSION = '0.78'
4
+ VERSION = '0.79'
5
5
  end
data/test/test_io.rb CHANGED
@@ -309,13 +309,13 @@ class IOClassMethodsTest < MiniTest::Test
309
309
  assert_equal BIN_DATA, s
310
310
  end
311
311
 
312
- def test_foreach
313
- skip 'IO.foreach is not yet implemented'
314
- lines = []
315
- IO.foreach(__FILE__) { |l| lines << l }
316
- assert_equal "# frozen_string_literal: true\n", lines[0]
317
- assert_equal "end\n", lines[-1]
318
- end
312
+ # def test_foreach
313
+ # skip 'IO.foreach is not yet implemented'
314
+ # lines = []
315
+ # IO.foreach(__FILE__) { |l| lines << l }
316
+ # assert_equal "# frozen_string_literal: true\n", lines[0]
317
+ # assert_equal "end\n", lines[-1]
318
+ # end
319
319
 
320
320
  def test_read_class_method
321
321
  s = IO.read(__FILE__)
data/test/test_signal.rb CHANGED
@@ -33,24 +33,24 @@ class SignalTrapTest < Minitest::Test
33
33
  Fiber.current.tag = :main
34
34
 
35
35
  expected = [
36
- [:fiber_switchpoint, :main],
37
- [:fiber_event_poll_enter, :main],
38
- [:fiber_create, :oob],
39
- [:fiber_schedule, :oob],
40
- [:fiber_event_poll_leave, :main],
41
- [:fiber_run, :oob],
42
- [:fiber_terminate, :oob],
43
- [:fiber_switchpoint, :oob],
44
- [:fiber_event_poll_enter, :oob],
45
- [:fiber_schedule, :main],
46
- [:fiber_event_poll_leave, :oob],
47
- [:fiber_run, :main]
36
+ [:block, :main],
37
+ [:enter_poll, :main],
38
+ [:spin, :oob],
39
+ [:schedule, :oob],
40
+ [:leave_poll, :main],
41
+ [:unblock, :oob],
42
+ [:terminate, :oob],
43
+ [:block, :oob],
44
+ [:enter_poll, :oob],
45
+ [:schedule, :main],
46
+ [:leave_poll, :oob],
47
+ [:unblock, :main]
48
48
  ]
49
49
  if Thread.backend.kind == :libev
50
50
  expected += [
51
- [:fiber_schedule, :main],
52
- [:fiber_switchpoint, :main],
53
- [:fiber_run, :main]
51
+ [:schedule, :main],
52
+ [:block, :main],
53
+ [:unblock, :main]
54
54
  ]
55
55
  end
56
56
 
data/test/test_thread.rb CHANGED
@@ -132,7 +132,7 @@ class ThreadTest < MiniTest::Test
132
132
  Thread.backend.trace_proc = proc {|*r| records << r }
133
133
  suspend
134
134
  assert_equal [
135
- [:fiber_switchpoint, Fiber.current, ["#{__FILE__}:#{__LINE__ - 2}:in `test_that_suspend_returns_immediately_if_no_watchers'"] + caller]
135
+ [:block, Fiber.current, ["#{__FILE__}:#{__LINE__ - 2}:in `test_that_suspend_returns_immediately_if_no_watchers'"] + caller]
136
136
  ], records
137
137
  ensure
138
138
  Thread.backend.trace_proc = nil
data/test/test_trace.rb CHANGED
@@ -1,17 +1,29 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'helper'
4
+ require 'polyphony/core/debug'
4
5
 
5
6
  class TraceTest < MiniTest::Test
6
7
  def test_tracing_enabled
7
8
  events = []
8
- Thread.backend.trace_proc = proc { |*e| events << e }
9
+
10
+ Thread.backend.trace_proc = proc { |*e|
11
+ case e[0]
12
+ when :schedule
13
+ e = e[0..3]
14
+ when :block
15
+ e = e[0..1]
16
+ when :unblock
17
+ e = e[0..2]
18
+ end
19
+ events << e
20
+ }
9
21
  snooze
10
22
 
11
23
  assert_equal [
12
- [:fiber_schedule, Fiber.current, nil, false],
13
- [:fiber_switchpoint, Fiber.current, ["#{__FILE__}:#{__LINE__ - 4}:in `test_tracing_enabled'"] + caller],
14
- [:fiber_run, Fiber.current, nil]
24
+ [:schedule, Fiber.current, nil, false],
25
+ [:block, Fiber.current],
26
+ [:unblock, Fiber.current, nil]
15
27
  ], events
16
28
  ensure
17
29
  Thread.backend.trace_proc = nil
@@ -19,7 +31,17 @@ class TraceTest < MiniTest::Test
19
31
 
20
32
  def test_2_fiber_trace
21
33
  events = []
22
- Thread.backend.trace_proc = proc { |*e| events << e }
34
+ Thread.backend.trace_proc = proc { |*e|
35
+ case e[0]
36
+ when :schedule
37
+ e = e[0..3]
38
+ when :spin, :block
39
+ e = e[0..1]
40
+ when :unblock
41
+ e = e[0..2]
42
+ end
43
+ events << e
44
+ }
23
45
 
24
46
  f = spin { sleep 0; :byebye }
25
47
  l0 = __LINE__ + 1
@@ -28,28 +50,84 @@ class TraceTest < MiniTest::Test
28
50
 
29
51
  Thread.backend.trace_proc = nil
30
52
 
31
- # remove caller info for :fiber_switchpoint events
32
- events.each {|e| e.pop if e[0] == :fiber_switchpoint }
33
-
34
53
  assert_equal [
35
- [:fiber_create, f],
36
- [:fiber_schedule, f, nil, false],
37
- [:fiber_switchpoint, Fiber.current],
38
- [:fiber_run, f, nil],
39
- [:fiber_switchpoint, f],
40
- [:fiber_event_poll_enter, f],
41
- [:fiber_schedule, f, nil, false],
42
- [:fiber_event_poll_leave, f],
43
- [:fiber_run, f, nil],
44
- [:fiber_terminate, f, :byebye],
45
- [:fiber_switchpoint, f],
46
- [:fiber_switchpoint, Fiber.current],
47
- [:fiber_event_poll_enter, Fiber.current],
48
- [:fiber_schedule, Fiber.current, nil, false],
49
- [:fiber_event_poll_leave, Fiber.current],
50
- [:fiber_run, Fiber.current, nil]
54
+ [:spin, f],
55
+ [:schedule, f, nil, false],
56
+ [:block, Fiber.current],
57
+ [:unblock, f, nil],
58
+ [:block, f],
59
+ [:enter_poll, f],
60
+ [:schedule, f, nil, false],
61
+ [:leave_poll, f],
62
+ [:unblock, f, nil],
63
+ [:terminate, f, :byebye],
64
+ [:block, f],
65
+ [:block, Fiber.current],
66
+ [:enter_poll, Fiber.current],
67
+ [:schedule, Fiber.current, nil, false],
68
+ [:leave_poll, Fiber.current],
69
+ [:unblock, Fiber.current, nil]
51
70
  ], events
52
71
  ensure
53
72
  Thread.backend.trace_proc = nil
54
73
  end
74
+
75
+ def test_event_firehose
76
+ buffer = []
77
+ Polyphony::Trace.start_event_firehose { |e| buffer << e }
78
+
79
+ f1 = spin(:f1) do
80
+ receive
81
+ end
82
+
83
+ f1 << :foo
84
+ f1.await
85
+
86
+ Thread.backend.trace_proc = nil
87
+
88
+ buffer.each { |e| e.delete(:stamp); e.delete(:caller) }
89
+
90
+ main = Fiber.current
91
+ assert_equal(
92
+ [
93
+ { event: :spin, fiber: f1, source_fiber: main },
94
+ { event: :schedule, fiber: f1, value: nil, source_fiber: main },
95
+ { event: :block, fiber: main },
96
+ { event: :unblock, fiber: f1, value: nil },
97
+ { event: :schedule, fiber: f1, value: nil, source_fiber: f1 },
98
+ { event: :block, fiber: f1, },
99
+ { event: :enter_poll },
100
+ { event: :leave_poll },
101
+ { event: :unblock, fiber: f1, value: nil },
102
+ { event: :terminate, fiber: f1, value: :foo },
103
+ { event: :schedule, fiber: main, value: nil, source_fiber: f1 },
104
+ { event: :block, fiber: f1 },
105
+ { event: :unblock, fiber: main, value: nil }
106
+ ], buffer
107
+ )
108
+ ensure
109
+ Thread.backend.trace_proc = nil
110
+ end
111
+
112
+ def test_event_firehose_with_io
113
+ r, w = IO.pipe
114
+ Polyphony::Trace.start_event_firehose(w)
115
+
116
+ f1 = spin(:f1) do
117
+ receive
118
+ end
119
+
120
+ f1 << :foo
121
+ f1.await
122
+
123
+ Thread.backend.trace_proc = nil
124
+ w.close
125
+
126
+ log = r.read
127
+ assert_equal 13, log.lines.size
128
+
129
+ # TODO: make sure log is formatted correctly
130
+ ensure
131
+ Thread.backend.trace_proc = nil
132
+ end
55
133
  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.78'
4
+ version: '0.79'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sharon Rosner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-02-16 00:00:00.000000000 Z
11
+ date: 2022-02-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake-compiler