pf2 0.1.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +29 -2
  3. data/Cargo.lock +650 -0
  4. data/Cargo.toml +3 -0
  5. data/README.md +110 -13
  6. data/Rakefile +8 -0
  7. data/crates/backtrace-sys2/.gitignore +1 -0
  8. data/crates/backtrace-sys2/Cargo.toml +9 -0
  9. data/crates/backtrace-sys2/build.rs +48 -0
  10. data/crates/backtrace-sys2/src/lib.rs +5 -0
  11. data/crates/backtrace-sys2/src/libbacktrace/.gitignore +15 -0
  12. data/crates/backtrace-sys2/src/libbacktrace/Isaac.Newton-Opticks.txt +9286 -0
  13. data/crates/backtrace-sys2/src/libbacktrace/LICENSE +29 -0
  14. data/crates/backtrace-sys2/src/libbacktrace/Makefile.am +623 -0
  15. data/crates/backtrace-sys2/src/libbacktrace/Makefile.in +2666 -0
  16. data/crates/backtrace-sys2/src/libbacktrace/README.md +36 -0
  17. data/crates/backtrace-sys2/src/libbacktrace/aclocal.m4 +864 -0
  18. data/crates/backtrace-sys2/src/libbacktrace/alloc.c +167 -0
  19. data/crates/backtrace-sys2/src/libbacktrace/allocfail.c +136 -0
  20. data/crates/backtrace-sys2/src/libbacktrace/allocfail.sh +104 -0
  21. data/crates/backtrace-sys2/src/libbacktrace/atomic.c +113 -0
  22. data/crates/backtrace-sys2/src/libbacktrace/backtrace-supported.h.in +66 -0
  23. data/crates/backtrace-sys2/src/libbacktrace/backtrace.c +129 -0
  24. data/crates/backtrace-sys2/src/libbacktrace/backtrace.h +189 -0
  25. data/crates/backtrace-sys2/src/libbacktrace/btest.c +501 -0
  26. data/crates/backtrace-sys2/src/libbacktrace/compile +348 -0
  27. data/crates/backtrace-sys2/src/libbacktrace/config/enable.m4 +38 -0
  28. data/crates/backtrace-sys2/src/libbacktrace/config/lead-dot.m4 +31 -0
  29. data/crates/backtrace-sys2/src/libbacktrace/config/libtool.m4 +7436 -0
  30. data/crates/backtrace-sys2/src/libbacktrace/config/ltoptions.m4 +369 -0
  31. data/crates/backtrace-sys2/src/libbacktrace/config/ltsugar.m4 +123 -0
  32. data/crates/backtrace-sys2/src/libbacktrace/config/ltversion.m4 +23 -0
  33. data/crates/backtrace-sys2/src/libbacktrace/config/lt~obsolete.m4 +98 -0
  34. data/crates/backtrace-sys2/src/libbacktrace/config/multi.m4 +68 -0
  35. data/crates/backtrace-sys2/src/libbacktrace/config/override.m4 +117 -0
  36. data/crates/backtrace-sys2/src/libbacktrace/config/unwind_ipinfo.m4 +37 -0
  37. data/crates/backtrace-sys2/src/libbacktrace/config/warnings.m4 +227 -0
  38. data/crates/backtrace-sys2/src/libbacktrace/config.guess +1700 -0
  39. data/crates/backtrace-sys2/src/libbacktrace/config.h.in +182 -0
  40. data/crates/backtrace-sys2/src/libbacktrace/config.sub +1885 -0
  41. data/crates/backtrace-sys2/src/libbacktrace/configure +15740 -0
  42. data/crates/backtrace-sys2/src/libbacktrace/configure.ac +613 -0
  43. data/crates/backtrace-sys2/src/libbacktrace/dwarf.c +4402 -0
  44. data/crates/backtrace-sys2/src/libbacktrace/edtest.c +120 -0
  45. data/crates/backtrace-sys2/src/libbacktrace/edtest2.c +43 -0
  46. data/crates/backtrace-sys2/src/libbacktrace/elf.c +7443 -0
  47. data/crates/backtrace-sys2/src/libbacktrace/fileline.c +407 -0
  48. data/crates/backtrace-sys2/src/libbacktrace/filenames.h +52 -0
  49. data/crates/backtrace-sys2/src/libbacktrace/filetype.awk +13 -0
  50. data/crates/backtrace-sys2/src/libbacktrace/install-debuginfo-for-buildid.sh.in +65 -0
  51. data/crates/backtrace-sys2/src/libbacktrace/install-sh +501 -0
  52. data/crates/backtrace-sys2/src/libbacktrace/instrumented_alloc.c +114 -0
  53. data/crates/backtrace-sys2/src/libbacktrace/internal.h +389 -0
  54. data/crates/backtrace-sys2/src/libbacktrace/libtool.m4 +7436 -0
  55. data/crates/backtrace-sys2/src/libbacktrace/ltmain.sh +8636 -0
  56. data/crates/backtrace-sys2/src/libbacktrace/ltoptions.m4 +369 -0
  57. data/crates/backtrace-sys2/src/libbacktrace/ltsugar.m4 +123 -0
  58. data/crates/backtrace-sys2/src/libbacktrace/ltversion.m4 +23 -0
  59. data/crates/backtrace-sys2/src/libbacktrace/lt~obsolete.m4 +98 -0
  60. data/crates/backtrace-sys2/src/libbacktrace/macho.c +1355 -0
  61. data/crates/backtrace-sys2/src/libbacktrace/missing +215 -0
  62. data/crates/backtrace-sys2/src/libbacktrace/mmap.c +331 -0
  63. data/crates/backtrace-sys2/src/libbacktrace/mmapio.c +110 -0
  64. data/crates/backtrace-sys2/src/libbacktrace/move-if-change +83 -0
  65. data/crates/backtrace-sys2/src/libbacktrace/mtest.c +410 -0
  66. data/crates/backtrace-sys2/src/libbacktrace/nounwind.c +66 -0
  67. data/crates/backtrace-sys2/src/libbacktrace/pecoff.c +957 -0
  68. data/crates/backtrace-sys2/src/libbacktrace/posix.c +104 -0
  69. data/crates/backtrace-sys2/src/libbacktrace/print.c +92 -0
  70. data/crates/backtrace-sys2/src/libbacktrace/read.c +110 -0
  71. data/crates/backtrace-sys2/src/libbacktrace/simple.c +108 -0
  72. data/crates/backtrace-sys2/src/libbacktrace/sort.c +108 -0
  73. data/crates/backtrace-sys2/src/libbacktrace/state.c +72 -0
  74. data/crates/backtrace-sys2/src/libbacktrace/stest.c +137 -0
  75. data/crates/backtrace-sys2/src/libbacktrace/test-driver +148 -0
  76. data/crates/backtrace-sys2/src/libbacktrace/test_format.c +55 -0
  77. data/crates/backtrace-sys2/src/libbacktrace/testlib.c +234 -0
  78. data/crates/backtrace-sys2/src/libbacktrace/testlib.h +110 -0
  79. data/crates/backtrace-sys2/src/libbacktrace/ttest.c +161 -0
  80. data/crates/backtrace-sys2/src/libbacktrace/unittest.c +92 -0
  81. data/crates/backtrace-sys2/src/libbacktrace/unknown.c +65 -0
  82. data/crates/backtrace-sys2/src/libbacktrace/xcoff.c +1606 -0
  83. data/crates/backtrace-sys2/src/libbacktrace/xztest.c +508 -0
  84. data/crates/backtrace-sys2/src/libbacktrace/zstdtest.c +523 -0
  85. data/crates/backtrace-sys2/src/libbacktrace/ztest.c +541 -0
  86. data/ext/pf2/Cargo.toml +25 -0
  87. data/ext/pf2/build.rs +3 -0
  88. data/ext/pf2/extconf.rb +6 -1
  89. data/ext/pf2/src/backtrace.rs +126 -0
  90. data/ext/pf2/src/lib.rs +15 -0
  91. data/ext/pf2/src/profile.rs +65 -0
  92. data/ext/pf2/src/profile_serializer.rs +204 -0
  93. data/ext/pf2/src/ringbuffer.rs +152 -0
  94. data/ext/pf2/src/ruby_init.rs +74 -0
  95. data/ext/pf2/src/sample.rs +66 -0
  96. data/ext/pf2/src/siginfo_t.c +5 -0
  97. data/ext/pf2/src/signal_scheduler/configuration.rs +31 -0
  98. data/ext/pf2/src/signal_scheduler/timer_installer.rs +199 -0
  99. data/ext/pf2/src/signal_scheduler.rs +311 -0
  100. data/ext/pf2/src/timer_thread_scheduler.rs +319 -0
  101. data/ext/pf2/src/util.rs +30 -0
  102. data/lib/pf2/cli.rb +1 -1
  103. data/lib/pf2/reporter.rb +48 -16
  104. data/lib/pf2/version.rb +1 -1
  105. data/lib/pf2.rb +20 -5
  106. metadata +128 -5
  107. data/ext/pf2/pf2.c +0 -246
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pf2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daisuke Aritomo
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-10-04 00:00:00.000000000 Z
11
+ date: 2024-02-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake-compiler
@@ -24,6 +24,34 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rb_sys
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.9.63
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.9.63
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
27
55
  description:
28
56
  email:
29
57
  - osyoyu@osyoyu.com
@@ -34,12 +62,107 @@ extensions:
34
62
  extra_rdoc_files: []
35
63
  files:
36
64
  - CHANGELOG.md
65
+ - Cargo.lock
66
+ - Cargo.toml
37
67
  - LICENSE.txt
38
68
  - README.md
39
69
  - Rakefile
70
+ - crates/backtrace-sys2/.gitignore
71
+ - crates/backtrace-sys2/Cargo.toml
72
+ - crates/backtrace-sys2/build.rs
73
+ - crates/backtrace-sys2/src/lib.rs
74
+ - crates/backtrace-sys2/src/libbacktrace/.gitignore
75
+ - crates/backtrace-sys2/src/libbacktrace/Isaac.Newton-Opticks.txt
76
+ - crates/backtrace-sys2/src/libbacktrace/LICENSE
77
+ - crates/backtrace-sys2/src/libbacktrace/Makefile.am
78
+ - crates/backtrace-sys2/src/libbacktrace/Makefile.in
79
+ - crates/backtrace-sys2/src/libbacktrace/README.md
80
+ - crates/backtrace-sys2/src/libbacktrace/aclocal.m4
81
+ - crates/backtrace-sys2/src/libbacktrace/alloc.c
82
+ - crates/backtrace-sys2/src/libbacktrace/allocfail.c
83
+ - crates/backtrace-sys2/src/libbacktrace/allocfail.sh
84
+ - crates/backtrace-sys2/src/libbacktrace/atomic.c
85
+ - crates/backtrace-sys2/src/libbacktrace/backtrace-supported.h.in
86
+ - crates/backtrace-sys2/src/libbacktrace/backtrace.c
87
+ - crates/backtrace-sys2/src/libbacktrace/backtrace.h
88
+ - crates/backtrace-sys2/src/libbacktrace/btest.c
89
+ - crates/backtrace-sys2/src/libbacktrace/compile
90
+ - crates/backtrace-sys2/src/libbacktrace/config.guess
91
+ - crates/backtrace-sys2/src/libbacktrace/config.h.in
92
+ - crates/backtrace-sys2/src/libbacktrace/config.sub
93
+ - crates/backtrace-sys2/src/libbacktrace/config/enable.m4
94
+ - crates/backtrace-sys2/src/libbacktrace/config/lead-dot.m4
95
+ - crates/backtrace-sys2/src/libbacktrace/config/libtool.m4
96
+ - crates/backtrace-sys2/src/libbacktrace/config/ltoptions.m4
97
+ - crates/backtrace-sys2/src/libbacktrace/config/ltsugar.m4
98
+ - crates/backtrace-sys2/src/libbacktrace/config/ltversion.m4
99
+ - crates/backtrace-sys2/src/libbacktrace/config/lt~obsolete.m4
100
+ - crates/backtrace-sys2/src/libbacktrace/config/multi.m4
101
+ - crates/backtrace-sys2/src/libbacktrace/config/override.m4
102
+ - crates/backtrace-sys2/src/libbacktrace/config/unwind_ipinfo.m4
103
+ - crates/backtrace-sys2/src/libbacktrace/config/warnings.m4
104
+ - crates/backtrace-sys2/src/libbacktrace/configure
105
+ - crates/backtrace-sys2/src/libbacktrace/configure.ac
106
+ - crates/backtrace-sys2/src/libbacktrace/dwarf.c
107
+ - crates/backtrace-sys2/src/libbacktrace/edtest.c
108
+ - crates/backtrace-sys2/src/libbacktrace/edtest2.c
109
+ - crates/backtrace-sys2/src/libbacktrace/elf.c
110
+ - crates/backtrace-sys2/src/libbacktrace/fileline.c
111
+ - crates/backtrace-sys2/src/libbacktrace/filenames.h
112
+ - crates/backtrace-sys2/src/libbacktrace/filetype.awk
113
+ - crates/backtrace-sys2/src/libbacktrace/install-debuginfo-for-buildid.sh.in
114
+ - crates/backtrace-sys2/src/libbacktrace/install-sh
115
+ - crates/backtrace-sys2/src/libbacktrace/instrumented_alloc.c
116
+ - crates/backtrace-sys2/src/libbacktrace/internal.h
117
+ - crates/backtrace-sys2/src/libbacktrace/libtool.m4
118
+ - crates/backtrace-sys2/src/libbacktrace/ltmain.sh
119
+ - crates/backtrace-sys2/src/libbacktrace/ltoptions.m4
120
+ - crates/backtrace-sys2/src/libbacktrace/ltsugar.m4
121
+ - crates/backtrace-sys2/src/libbacktrace/ltversion.m4
122
+ - crates/backtrace-sys2/src/libbacktrace/lt~obsolete.m4
123
+ - crates/backtrace-sys2/src/libbacktrace/macho.c
124
+ - crates/backtrace-sys2/src/libbacktrace/missing
125
+ - crates/backtrace-sys2/src/libbacktrace/mmap.c
126
+ - crates/backtrace-sys2/src/libbacktrace/mmapio.c
127
+ - crates/backtrace-sys2/src/libbacktrace/move-if-change
128
+ - crates/backtrace-sys2/src/libbacktrace/mtest.c
129
+ - crates/backtrace-sys2/src/libbacktrace/nounwind.c
130
+ - crates/backtrace-sys2/src/libbacktrace/pecoff.c
131
+ - crates/backtrace-sys2/src/libbacktrace/posix.c
132
+ - crates/backtrace-sys2/src/libbacktrace/print.c
133
+ - crates/backtrace-sys2/src/libbacktrace/read.c
134
+ - crates/backtrace-sys2/src/libbacktrace/simple.c
135
+ - crates/backtrace-sys2/src/libbacktrace/sort.c
136
+ - crates/backtrace-sys2/src/libbacktrace/state.c
137
+ - crates/backtrace-sys2/src/libbacktrace/stest.c
138
+ - crates/backtrace-sys2/src/libbacktrace/test-driver
139
+ - crates/backtrace-sys2/src/libbacktrace/test_format.c
140
+ - crates/backtrace-sys2/src/libbacktrace/testlib.c
141
+ - crates/backtrace-sys2/src/libbacktrace/testlib.h
142
+ - crates/backtrace-sys2/src/libbacktrace/ttest.c
143
+ - crates/backtrace-sys2/src/libbacktrace/unittest.c
144
+ - crates/backtrace-sys2/src/libbacktrace/unknown.c
145
+ - crates/backtrace-sys2/src/libbacktrace/xcoff.c
146
+ - crates/backtrace-sys2/src/libbacktrace/xztest.c
147
+ - crates/backtrace-sys2/src/libbacktrace/zstdtest.c
148
+ - crates/backtrace-sys2/src/libbacktrace/ztest.c
40
149
  - exe/pf2
150
+ - ext/pf2/Cargo.toml
151
+ - ext/pf2/build.rs
41
152
  - ext/pf2/extconf.rb
42
- - ext/pf2/pf2.c
153
+ - ext/pf2/src/backtrace.rs
154
+ - ext/pf2/src/lib.rs
155
+ - ext/pf2/src/profile.rs
156
+ - ext/pf2/src/profile_serializer.rs
157
+ - ext/pf2/src/ringbuffer.rs
158
+ - ext/pf2/src/ruby_init.rs
159
+ - ext/pf2/src/sample.rs
160
+ - ext/pf2/src/siginfo_t.c
161
+ - ext/pf2/src/signal_scheduler.rs
162
+ - ext/pf2/src/signal_scheduler/configuration.rs
163
+ - ext/pf2/src/signal_scheduler/timer_installer.rs
164
+ - ext/pf2/src/timer_thread_scheduler.rs
165
+ - ext/pf2/src/util.rs
43
166
  - lib/pf2.rb
44
167
  - lib/pf2/cli.rb
45
168
  - lib/pf2/reporter.rb
@@ -60,14 +183,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
60
183
  requirements:
61
184
  - - ">="
62
185
  - !ruby/object:Gem::Version
63
- version: 3.3.0.dev
186
+ version: 3.3.0
64
187
  required_rubygems_version: !ruby/object:Gem::Requirement
65
188
  requirements:
66
189
  - - ">="
67
190
  - !ruby/object:Gem::Version
68
191
  version: '0'
69
192
  requirements: []
70
- rubygems_version: 3.5.0.dev
193
+ rubygems_version: 3.6.0.dev
71
194
  signing_key:
72
195
  specification_version: 4
73
196
  summary: Yet another Ruby profiler
data/ext/pf2/pf2.c DELETED
@@ -1,246 +0,0 @@
1
- #include <errno.h>
2
- #include <signal.h>
3
- #include <stdbool.h>
4
- #include <stdio.h>
5
- #include <stdlib.h>
6
- #include <unistd.h>
7
-
8
- #include <ruby.h>
9
- #include <ruby/debug.h>
10
- #include <ruby/thread.h>
11
-
12
- #define MAX_BUFFER_SIZE 3000
13
-
14
- struct pf2_buffer_t {
15
- VALUE framebuffer[MAX_BUFFER_SIZE];
16
- int linebuffer[MAX_BUFFER_SIZE];
17
- };
18
-
19
- // Ruby functions
20
- void Init_pf2(void);
21
- VALUE rb_start(VALUE self, VALUE debug);
22
- VALUE rb_stop(VALUE self);
23
-
24
- static void pf2_start(void);
25
- static void pf2_stop(void);
26
- static void pf2_signal_handler(int signo);
27
- static void pf2_postponed_job(void *_);
28
-
29
- static void pf2_record(struct pf2_buffer_t *buffer);
30
- static VALUE find_or_create_thread_results(VALUE results, pid_t thread_id);
31
-
32
- // Buffer to record rb_profile_frames() results
33
- struct pf2_buffer_t buffer;
34
- // The time when the profiler started
35
- struct timespec initial_time;
36
- // Debug print?
37
- bool _debug = false;
38
-
39
- void
40
- Init_pf2(void)
41
- {
42
- VALUE rb_mPf2 = rb_define_module("Pf2");
43
- rb_define_module_function(rb_mPf2, "start", rb_start, 1);
44
- rb_define_module_function(rb_mPf2, "stop", rb_stop, 0);
45
- }
46
-
47
- VALUE
48
- rb_start(VALUE self, VALUE debug) {
49
- _debug = RTEST(debug);
50
-
51
- /**
52
- * {
53
- * sequence: 0,
54
- * threads: {},
55
- * }
56
- */
57
- VALUE results = rb_hash_new();
58
- rb_hash_aset(results, ID2SYM(rb_intern_const("sequence")), INT2FIX(0));
59
- rb_hash_aset(results, ID2SYM(rb_intern_const("threads")), rb_hash_new());
60
-
61
- rb_iv_set(self, "@results", results);
62
-
63
- pf2_start();
64
-
65
- if (_debug) {
66
- rb_funcall(rb_mKernel, rb_intern("puts"), 1, rb_str_new_cstr("[debug] Pf2 started"));
67
- }
68
-
69
- return results;
70
- }
71
-
72
- VALUE
73
- rb_stop(VALUE self) {
74
- pf2_stop();
75
-
76
- if (_debug) {
77
- rb_funcall(rb_mKernel, rb_intern("puts"), 1, rb_str_new_cstr("[debug] Pf2 stopped"));
78
- }
79
-
80
- return rb_iv_get(self, "@results");
81
- }
82
-
83
- static void
84
- pf2_start(void)
85
- {
86
- clock_gettime(CLOCK_MONOTONIC, &initial_time);
87
-
88
- // Configure timer for every 10 ms
89
- // TODO: Make interval configurable
90
- struct itimerval timer;
91
- timer.it_value.tv_sec = 1;
92
- timer.it_value.tv_usec = 0;
93
- timer.it_interval.tv_sec = 0;
94
- timer.it_interval.tv_usec = 10 * 1000; // 10 ms
95
- if (signal(SIGALRM, pf2_signal_handler) == SIG_ERR) {
96
- rb_syserr_fail(errno, "Failed to configure profiling timer");
97
- };
98
- if (setitimer(ITIMER_REAL, &timer, NULL) == -1) {
99
- rb_syserr_fail(errno, "Failed to configure profiling timer");
100
- };
101
- }
102
-
103
- static void
104
- pf2_stop(void)
105
- {
106
- struct itimerval timer = { 0 }; // stop
107
- setitimer(ITIMER_REAL, &timer, NULL);
108
- }
109
-
110
- // async-signal-safe
111
- static void
112
- pf2_signal_handler(int signo)
113
- {
114
- rb_postponed_job_register_one(0, pf2_postponed_job, 0);
115
- }
116
-
117
- static void
118
- pf2_postponed_job(void *_) {
119
- pf2_record(&buffer);
120
- };
121
-
122
- // Buffer structure
123
- static void
124
- pf2_record(struct pf2_buffer_t *buffer)
125
- {
126
- // get the current time
127
- struct timespec ts;
128
- clock_gettime(CLOCK_MONOTONIC, &ts);
129
-
130
- VALUE rb_mPf2 = rb_const_get(rb_cObject, rb_intern("Pf2"));
131
- VALUE results = rb_iv_get(rb_mPf2, "@results");
132
-
133
- // Iterate over all Threads
134
- VALUE threads = rb_iv_get(rb_mPf2, "@@threads");
135
- for (int i = 0; i < RARRAY_LEN(threads); i++) {
136
- VALUE thread = rb_ary_entry(threads, i);
137
- VALUE thread_status = rb_funcall(thread, rb_intern("status"), 0);
138
- if (NIL_P(thread) || thread_status == Qfalse) {
139
- // Thread is dead, just ignore
140
- continue;
141
- }
142
-
143
- pid_t thread_id = NUM2INT(rb_funcall(thread, rb_intern("native_thread_id"), 0));
144
- VALUE thread_results = find_or_create_thread_results(results, thread_id);
145
- assert(!NIL_P(thread_results));
146
-
147
- // The actual querying
148
- int stack_depth = rb_profile_thread_frames(thread, 0, MAX_BUFFER_SIZE, buffer->framebuffer, buffer->linebuffer);
149
-
150
- // TODO: Reimplement Pf2-internal data structures without CRuby
151
- // (which will allow us to release the GVL at this point)
152
- // rb_thread_call_without_gvl(...);
153
-
154
- VALUE frames_table = rb_hash_lookup(thread_results, ID2SYM(rb_intern_const("frames")));
155
- assert(!NIL_P(frames_table));
156
- VALUE samples = rb_hash_lookup(thread_results, ID2SYM(rb_intern_const("samples")));
157
- assert(!NIL_P(samples));
158
-
159
- // Dig down the stack (top of call stack -> bottom (root))
160
- VALUE stack_tree_p = rb_hash_lookup(thread_results, ID2SYM(rb_intern_const("stack_tree")));
161
- for (int i = stack_depth - 1; i >= 0; i--) {
162
- assert(NIL_P(buffer->framebuffer[i]));
163
-
164
- // Collect & record frame information
165
- VALUE frame_obj_id = rb_obj_id(buffer->framebuffer[i]);
166
- VALUE frame_table_entry = rb_hash_aref(frames_table, frame_obj_id);
167
- if (NIL_P(frame_table_entry)) {
168
- frame_table_entry = rb_hash_new();
169
- rb_hash_aset(frame_table_entry, ID2SYM(rb_intern_const("full_label")), rb_profile_frame_full_label(buffer->framebuffer[i]));
170
- rb_hash_aset(frames_table, frame_obj_id, frame_table_entry);
171
- }
172
-
173
- VALUE children = rb_hash_aref(stack_tree_p, ID2SYM(rb_intern_const("children")));
174
- VALUE next_node = rb_hash_lookup(children, frame_obj_id);
175
- // If this is the first time we see this frame, register it to the stack tree
176
- if (NIL_P(next_node)) { // not found
177
- next_node = rb_hash_new();
178
-
179
- // Increment sequence
180
- VALUE next =
181
- rb_funcall(
182
- rb_hash_lookup(results, ID2SYM(rb_intern_const("sequence"))),
183
- rb_intern("+"),
184
- 1,
185
- INT2FIX(1)
186
- );
187
- rb_hash_aset(results, ID2SYM(rb_intern_const("sequence")), next);
188
-
189
- rb_hash_aset(next_node, ID2SYM(rb_intern_const("node_id")), INT2FIX(next));
190
- rb_hash_aset(next_node, ID2SYM(rb_intern_const("frame_id")), frame_obj_id);
191
- rb_hash_aset(next_node, ID2SYM(rb_intern_const("full_label")), rb_profile_frame_full_label(buffer->framebuffer[i]));
192
- rb_hash_aset(next_node, ID2SYM(rb_intern_const("children")), rb_hash_new());
193
-
194
- rb_hash_aset(children, frame_obj_id, next_node);
195
- }
196
-
197
- VALUE stack_tree_id = rb_hash_aref(next_node, ID2SYM(rb_intern_const("node_id")));
198
-
199
- // If on leaf
200
- if (i == 0) {
201
- // Record sample
202
- VALUE sample = rb_hash_new();
203
- rb_hash_aset(sample, ID2SYM(rb_intern_const("stack_tree_id")), stack_tree_id);
204
- unsigned long long nsec = (ts.tv_sec - initial_time.tv_sec) * 1000000000 + ts.tv_nsec - initial_time.tv_nsec;
205
- rb_hash_aset(sample, ID2SYM(rb_intern_const("timestamp")), ULL2NUM(nsec));
206
- rb_ary_push(samples, sample);
207
- }
208
-
209
- stack_tree_p = next_node;
210
- }
211
- }
212
- }
213
-
214
- static VALUE
215
- find_or_create_thread_results(VALUE results, pid_t thread_id) {
216
- assert(!NIL_P(results));
217
- assert(!NIL_P(thread));
218
-
219
- VALUE threads = rb_hash_aref(results, ID2SYM(rb_intern_const("threads")));
220
- VALUE thread_results = rb_hash_aref(threads, INT2NUM(thread_id));
221
- if (NIL_P(thread_results)) {
222
- /**
223
- * {
224
- * thread_id: 1,
225
- * frames: [],
226
- * stack_tree: {
227
- * node_id: ...,
228
- * children: {}
229
- * },
230
- * samples: [],
231
- * }
232
- */
233
- thread_results = rb_hash_new();
234
- rb_hash_aset(thread_results, ID2SYM(rb_intern_const("thread_id")), INT2NUM(thread_id));
235
-
236
- rb_hash_aset(thread_results, ID2SYM(rb_intern_const("frames")), rb_hash_new());
237
- VALUE stack_tree = rb_hash_aset(thread_results, ID2SYM(rb_intern_const("stack_tree")), rb_hash_new());
238
- rb_hash_aset(stack_tree, ID2SYM(rb_intern_const("node_id")), ID2SYM(rb_intern_const("root")));
239
- rb_hash_aset(stack_tree, ID2SYM(rb_intern_const("children")), rb_hash_new());
240
- rb_hash_aset(thread_results, ID2SYM(rb_intern_const("samples")), rb_ary_new());
241
- rb_hash_aset(thread_results, ID2SYM(rb_intern_const("gvl_timings")), rb_ary_new());
242
-
243
- rb_hash_aset(threads, INT2NUM(thread_id), thread_results);
244
- }
245
- return thread_results;
246
- }