fiber-profiler 0.1.1 → 0.1.3
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
- checksums.yaml.gz.sig +0 -0
- data/ext/fiber/profiler/capture.c +59 -26
- data/lib/fiber/profiler/version.rb +1 -1
- data/readme.md +4 -0
- data/releases.md +4 -0
- data.tar.gz.sig +0 -0
- metadata +2 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a2bbdd5d629b193bb2c9fe87a9935abda45b21339bc9fa8e9a177a3cb08c6ca4
|
4
|
+
data.tar.gz: c38ff2d79d1dcc2cef0745923da73c0e1bfda612623d1592fffbeb708d6ff97f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a23c926af43a1db2f2cf71b269bbb63d0bff602ca17b40ced3da152dd317d084c2f41f47c42ba7194a7be67df6be8d17de54a829808a82173bb3dc83303b14bd
|
7
|
+
data.tar.gz: afd379c5f799fda50fa7229f4512ff01297e9f7f66a32d0eaab575a77c3b66d9b7cc1d13627609193983173b725b8851bf9240ab8096881bc764b66ba83b9a73
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
@@ -73,12 +73,14 @@ struct Fiber_Profiler_Capture {
|
|
73
73
|
// Calls that are shorter than this filter threshold will be ignored:
|
74
74
|
double filter_threshold;
|
75
75
|
|
76
|
+
// Output handling:
|
76
77
|
VALUE output;
|
77
78
|
Fiber_Profiler_Stream_Print print;
|
78
79
|
struct Fiber_Profiler_Stream stream;
|
79
80
|
|
80
81
|
// Whether or not the profiler is currently running:
|
81
82
|
int running;
|
83
|
+
VALUE thread;
|
82
84
|
|
83
85
|
// Whether or not to capture call data:
|
84
86
|
int capture;
|
@@ -133,6 +135,7 @@ void Fiber_Profiler_Capture_Call_free(void *element) {
|
|
133
135
|
static void Fiber_Profiler_Capture_mark(void *ptr) {
|
134
136
|
struct Fiber_Profiler_Capture *profiler = (struct Fiber_Profiler_Capture*)ptr;
|
135
137
|
|
138
|
+
rb_gc_mark_movable(profiler->thread);
|
136
139
|
rb_gc_mark_movable(profiler->output);
|
137
140
|
|
138
141
|
// If `klass` is stored as a VALUE in calls, we need to mark them here:
|
@@ -144,6 +147,7 @@ static void Fiber_Profiler_Capture_mark(void *ptr) {
|
|
144
147
|
static void Fiber_Profiler_Capture_compact(void *ptr) {
|
145
148
|
struct Fiber_Profiler_Capture *profiler = (struct Fiber_Profiler_Capture*)ptr;
|
146
149
|
|
150
|
+
profiler->thread = rb_gc_location(profiler->thread);
|
147
151
|
profiler->output = rb_gc_location(profiler->output);
|
148
152
|
|
149
153
|
// If `klass` is stored as a VALUE in calls, we need to update their locations here:
|
@@ -211,10 +215,12 @@ VALUE Fiber_Profiler_Capture_allocate(VALUE klass) {
|
|
211
215
|
struct Fiber_Profiler_Capture *profiler = ALLOC(struct Fiber_Profiler_Capture);
|
212
216
|
|
213
217
|
// Initialize the profiler state:
|
214
|
-
Fiber_Profiler_Capture_output_set(profiler, rb_stderr);
|
215
218
|
Fiber_Profiler_Stream_initialize(&profiler->stream);
|
219
|
+
profiler->output = Qnil;
|
216
220
|
|
217
221
|
profiler->running = 0;
|
222
|
+
profiler->thread = Qnil;
|
223
|
+
|
218
224
|
profiler->capture = 0;
|
219
225
|
profiler->stalls = 0;
|
220
226
|
profiler->nesting = 0;
|
@@ -258,6 +264,9 @@ VALUE Fiber_Profiler_Capture_initialize(int argc, VALUE *argv, VALUE self) {
|
|
258
264
|
|
259
265
|
if (arguments[3] != Qundef) {
|
260
266
|
Fiber_Profiler_Capture_output_set(profiler, arguments[3]);
|
267
|
+
} else {
|
268
|
+
// Initialize the profiler output - we dup `rb_stderr` because the profiler may otherwise run into synchronization issues with other uses of `rb_stderr`:
|
269
|
+
Fiber_Profiler_Capture_output_set(profiler, rb_obj_dup(rb_stderr));
|
261
270
|
}
|
262
271
|
|
263
272
|
return self;
|
@@ -324,16 +333,9 @@ static struct Fiber_Profiler_Capture_Call* profiler_event_record_call(struct Fib
|
|
324
333
|
return call;
|
325
334
|
}
|
326
335
|
|
327
|
-
void Fiber_Profiler_Capture_fiber_switch(struct Fiber_Profiler_Capture *profiler);
|
328
|
-
|
329
336
|
static void Fiber_Profiler_Capture_callback(rb_event_flag_t event_flag, VALUE data, VALUE self, ID id, VALUE klass) {
|
330
337
|
struct Fiber_Profiler_Capture *profiler = Fiber_Profiler_Capture_get(data);
|
331
338
|
|
332
|
-
if (event_flag & RUBY_EVENT_FIBER_SWITCH) {
|
333
|
-
Fiber_Profiler_Capture_fiber_switch(profiler);
|
334
|
-
return;
|
335
|
-
}
|
336
|
-
|
337
339
|
// We don't want to capture data if we're not running:
|
338
340
|
if (!profiler->capture) return;
|
339
341
|
|
@@ -373,17 +375,24 @@ static void Fiber_Profiler_Capture_callback(rb_event_flag_t event_flag, VALUE da
|
|
373
375
|
}
|
374
376
|
}
|
375
377
|
|
376
|
-
|
378
|
+
void Fiber_Profiler_Capture_pause(VALUE self) {
|
377
379
|
struct Fiber_Profiler_Capture *profiler = Fiber_Profiler_Capture_get(self);
|
378
380
|
|
379
|
-
if (profiler->
|
381
|
+
if (!profiler->capture) return;
|
380
382
|
|
381
|
-
profiler->
|
383
|
+
profiler->capture = 0;
|
382
384
|
|
383
|
-
|
384
|
-
|
385
|
+
rb_thread_remove_event_hook_with_data(profiler->thread, Fiber_Profiler_Capture_callback, self);
|
386
|
+
}
|
387
|
+
|
388
|
+
void Fiber_Profiler_Capture_resume(VALUE self) {
|
389
|
+
struct Fiber_Profiler_Capture *profiler = Fiber_Profiler_Capture_get(self);
|
385
390
|
|
386
|
-
|
391
|
+
if (profiler->capture) return;
|
392
|
+
|
393
|
+
profiler->capture = 1;
|
394
|
+
|
395
|
+
rb_event_flag_t event_flags = 0;
|
387
396
|
|
388
397
|
if (profiler->track_calls) {
|
389
398
|
event_flags |= RUBY_EVENT_CALL | RUBY_EVENT_RETURN;
|
@@ -391,12 +400,29 @@ VALUE Fiber_Profiler_Capture_start(VALUE self) {
|
|
391
400
|
// event_flags |= RUBY_EVENT_B_CALL | RUBY_EVENT_B_RETURN;
|
392
401
|
}
|
393
402
|
|
394
|
-
|
395
|
-
rb_thread_add_event_hook(thread, Fiber_Profiler_Capture_callback, event_flags, self);
|
403
|
+
// CRuby will raise an exception if you try to add "INTERNAL_EVENT" hooks at the same time as other hooks, so we do it in two calls:
|
404
|
+
rb_thread_add_event_hook(profiler->thread, Fiber_Profiler_Capture_callback, event_flags, self);
|
405
|
+
rb_thread_add_event_hook(profiler->thread, Fiber_Profiler_Capture_callback, RUBY_INTERNAL_EVENT_GC_START | RUBY_INTERNAL_EVENT_GC_END_SWEEP, self);
|
406
|
+
}
|
407
|
+
|
408
|
+
void Fiber_Profiler_Capture_fiber_switch(VALUE self);
|
409
|
+
|
410
|
+
void Fiber_Profiler_Capture_fiber_switch_callback(rb_event_flag_t event_flag, VALUE data, VALUE self, ID id, VALUE klass) {
|
411
|
+
Fiber_Profiler_Capture_fiber_switch(data);
|
412
|
+
}
|
413
|
+
|
414
|
+
VALUE Fiber_Profiler_Capture_start(VALUE self) {
|
415
|
+
struct Fiber_Profiler_Capture *profiler = Fiber_Profiler_Capture_get(self);
|
416
|
+
|
417
|
+
if (profiler->running) return Qfalse;
|
418
|
+
|
419
|
+
profiler->running = 1;
|
420
|
+
profiler->thread = rb_thread_current();
|
421
|
+
|
422
|
+
Fiber_Profiler_Capture_reset(profiler);
|
423
|
+
Fiber_Profiler_Time_current(&profiler->start_time);
|
396
424
|
|
397
|
-
|
398
|
-
rb_thread_add_event_hook(thread, Fiber_Profiler_Capture_callback, RUBY_INTERNAL_EVENT_GC_START | RUBY_INTERNAL_EVENT_GC_END_SWEEP, self);
|
399
|
-
// }
|
425
|
+
rb_thread_add_event_hook(profiler->thread, Fiber_Profiler_Capture_fiber_switch_callback, RUBY_EVENT_FIBER_SWITCH, self);
|
400
426
|
|
401
427
|
return self;
|
402
428
|
}
|
@@ -406,11 +432,13 @@ VALUE Fiber_Profiler_Capture_stop(VALUE self) {
|
|
406
432
|
|
407
433
|
if (!profiler->running) return Qfalse;
|
408
434
|
|
409
|
-
|
435
|
+
Fiber_Profiler_Capture_pause(self);
|
410
436
|
|
411
|
-
|
412
|
-
rb_thread_remove_event_hook_with_data(thread, Fiber_Profiler_Capture_callback, self);
|
437
|
+
rb_thread_remove_event_hook_with_data(profiler->thread, Fiber_Profiler_Capture_fiber_switch_callback, self);
|
413
438
|
|
439
|
+
profiler->running = 0;
|
440
|
+
profiler->thread = Qnil;
|
441
|
+
|
414
442
|
Fiber_Profiler_Time_current(&profiler->stop_time);
|
415
443
|
Fiber_Profiler_Capture_reset(profiler);
|
416
444
|
|
@@ -452,26 +480,29 @@ int Fiber_Profiler_Capture_sample(struct Fiber_Profiler_Capture *profiler) {
|
|
452
480
|
}
|
453
481
|
}
|
454
482
|
|
455
|
-
void Fiber_Profiler_Capture_fiber_switch(
|
483
|
+
void Fiber_Profiler_Capture_fiber_switch(VALUE self)
|
456
484
|
{
|
485
|
+
struct Fiber_Profiler_Capture *profiler = Fiber_Profiler_Capture_get(self);
|
457
486
|
float duration = Fiber_Profiler_Capture_duration(profiler);
|
458
487
|
|
459
488
|
if (profiler->capture) {
|
489
|
+
Fiber_Profiler_Capture_pause(self);
|
490
|
+
|
460
491
|
Fiber_Profiler_Capture_finish(profiler);
|
461
492
|
|
462
493
|
if (duration > profiler->stall_threshold) {
|
463
494
|
profiler->stalls += 1;
|
464
495
|
Fiber_Profiler_Capture_print(profiler);
|
465
496
|
}
|
497
|
+
|
498
|
+
Fiber_Profiler_Capture_reset(profiler);
|
466
499
|
}
|
467
500
|
|
468
|
-
Fiber_Profiler_Capture_reset(profiler);
|
469
|
-
|
470
501
|
if (Fiber_Profiler_Capture_sample(profiler)) {
|
471
502
|
// Reset the start time:
|
472
503
|
Fiber_Profiler_Time_current(&profiler->start_time);
|
473
504
|
|
474
|
-
|
505
|
+
Fiber_Profiler_Capture_resume(self);
|
475
506
|
}
|
476
507
|
}
|
477
508
|
|
@@ -560,6 +591,8 @@ void Fiber_Profiler_Capture_print_json(struct Fiber_Profiler_Capture *profiler,
|
|
560
591
|
}
|
561
592
|
|
562
593
|
void Fiber_Profiler_Capture_print(struct Fiber_Profiler_Capture *profiler) {
|
594
|
+
if (profiler->output == Qnil) return;
|
595
|
+
|
563
596
|
FILE *stream = profiler->stream.file;
|
564
597
|
profiler->print(profiler, stream);
|
565
598
|
fflush(stream);
|
data/readme.md
CHANGED
@@ -18,6 +18,10 @@ Please see the [project documentation](https://socketry.github.io/fiber-profiler
|
|
18
18
|
|
19
19
|
Please see the [project releases](https://socketry.github.io/fiber-profiler/releases/index) for all releases.
|
20
20
|
|
21
|
+
### v0.1.3
|
22
|
+
|
23
|
+
- Improved performance when not profiling (when sampling is enabled).
|
24
|
+
|
21
25
|
### v0.1.0
|
22
26
|
|
23
27
|
- Initial implementation extracted from `io-event` gem.
|
data/releases.md
CHANGED
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fiber-profiler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
@@ -36,7 +36,7 @@ cert_chain:
|
|
36
36
|
Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
|
37
37
|
voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
|
38
38
|
-----END CERTIFICATE-----
|
39
|
-
date: 2025-02-
|
39
|
+
date: 2025-02-14 00:00:00.000000000 Z
|
40
40
|
dependencies: []
|
41
41
|
executables: []
|
42
42
|
extensions:
|
metadata.gz.sig
CHANGED
Binary file
|