Skip to content

Commit 3f14ec2

Browse files
committed
Use Fiber.blocking{...} for writing to prevent context switching.
1 parent 0681a48 commit 3f14ec2

1 file changed

Lines changed: 27 additions & 1 deletion

File tree

ext/fiber/profiler/capture.c

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -754,14 +754,40 @@ void Fiber_Profiler_Capture_print_json(struct Fiber_Profiler_Capture *capture, F
754754
fprintf(stream, ",\"switches\":%zu,\"samples\":%zu,\"stalls\":%zu}\n", capture->switches, capture->samples, capture->stalls);
755755
}
756756

757+
VALUE output_write(RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, data))
758+
{
759+
struct Fiber_Profiler_Capture *capture = (struct Fiber_Profiler_Capture*)data;
760+
761+
// Actually perform the write to IO here.
762+
rb_io_write(
763+
capture->output,
764+
rb_str_new_static(capture->stream.buffer, capture->stream.size)
765+
);
766+
767+
return Qnil;
768+
}
769+
757770
void Fiber_Profiler_Capture_print(struct Fiber_Profiler_Capture *capture, double duration) {
771+
static VALUE Fiber = Qnil;
772+
773+
if (Fiber == Qnil) {
774+
Fiber = rb_const_get(rb_cObject, rb_intern("Fiber"));
775+
}
776+
758777
if (capture->output == Qnil) return;
759778

760779
FILE *stream = capture->stream.file;
761780
capture->print(capture, stream, duration);
762781
fflush(stream);
763782

764-
rb_io_write(capture->output, rb_str_new_static(capture->stream.buffer, capture->stream.size));
783+
// Do the actual write in Fiber.blocking.
784+
rb_block_call(
785+
Fiber,
786+
rb_intern("blocking"),
787+
0, NULL, // no args
788+
output_write,
789+
(VALUE)capture
790+
);
765791

766792
fseek(stream, 0, SEEK_SET);
767793
}

0 commit comments

Comments
 (0)