vernier 0.2.0 → 0.2.1

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: da6d8fafb453c25b5f1127a33c53401150cb91bf604a37db971c952ec490d900
4
- data.tar.gz: 97cc5b3435335fe97c531122d5692a3af3264c5abeb34eafb1a1808743b017fe
3
+ metadata.gz: dcfae18cfffd67e1e8a52c0c9de2654e7523b674d492964dfa3447c967d981e3
4
+ data.tar.gz: 4ff2a81a37d19f974914a0ff3fa28937302a636721b8732f7e7b282f895db9f3
5
5
  SHA512:
6
- metadata.gz: 92529d7331c8a015c900227f1d28b093322dfb386ce99213c4a22dea168d433f9e0d9ae221c3171ea7e3c91fd67753a9da668140af97f62e0edec08341cb4f63
7
- data.tar.gz: bdd0baaf24abdbed97f603da42e827fa10442f4f702f15a5ee2f01e2b25eb893465d8b313bcd3dec84a402d76554aa58d28547e2bad401db2c4dbb24797a2414
6
+ metadata.gz: bd4e4f001047bb3f20c9c0670339747b9e29abf6e44bcd77dbb38fcf7c16f42d33eef893045ab7a899b155d9b98765950e91af79864234a2d66243490d367d49
7
+ data.tar.gz: 14cecc8aa1058b4e38f130bed6ec1d43e8a59a636c125862ef6c61df13f885e1d76b1a142d0fa8fab16ea6bfee2642b7cd606bb562020f800ce3518b2c7fac2c
@@ -2,7 +2,7 @@
2
2
 
3
3
  require "mkmf"
4
4
 
5
- $CXXFLAGS += " -std=c++17 "
5
+ $CXXFLAGS += " -std=c++14 "
6
6
  $CXXFLAGS += " -ggdb3 -Og "
7
7
 
8
8
  create_makefile("vernier/vernier")
@@ -9,18 +9,19 @@
9
9
  #include <cassert>
10
10
  #include <atomic>
11
11
  #include <mutex>
12
- #include <optional>
13
12
 
14
13
  #include <sys/time.h>
15
14
  #include <signal.h>
16
15
  #ifdef __APPLE__
16
+ /* macOS */
17
17
  #include <dispatch/dispatch.h>
18
18
  #else
19
+ /* Linux */
19
20
  #include <semaphore.h>
21
+ #include <sys/syscall.h> /* for SYS_gettid */
20
22
  #endif
21
23
 
22
24
  #include "vernier.hh"
23
- #include "stack.hh"
24
25
 
25
26
  #include "ruby/ruby.h"
26
27
  #include "ruby/debug.h"
@@ -149,6 +150,69 @@ std::ostream& operator<<(std::ostream& os, const TimeStamp& info) {
149
150
  return os;
150
151
  }
151
152
 
153
+ struct FrameInfo {
154
+ static const char *label_cstr(VALUE frame) {
155
+ VALUE label = rb_profile_frame_full_label(frame);
156
+ return StringValueCStr(label);
157
+ }
158
+
159
+ static const char *file_cstr(VALUE frame) {
160
+ VALUE file = rb_profile_frame_absolute_path(frame);
161
+ if (NIL_P(file))
162
+ file = rb_profile_frame_path(frame);
163
+ if (NIL_P(file)) {
164
+ return "";
165
+ } else {
166
+ return StringValueCStr(file);
167
+ }
168
+ }
169
+
170
+ static int first_lineno_int(VALUE frame) {
171
+ VALUE first_lineno = rb_profile_frame_first_lineno(frame);
172
+ return NIL_P(first_lineno) ? 0 : FIX2INT(first_lineno);
173
+ }
174
+
175
+ FrameInfo(VALUE frame) :
176
+ label(label_cstr(frame)),
177
+ file(file_cstr(frame)),
178
+ first_lineno(first_lineno_int(frame)) { }
179
+
180
+ std::string label;
181
+ std::string file;
182
+ int first_lineno;
183
+ };
184
+
185
+ bool operator==(const FrameInfo& lhs, const FrameInfo& rhs) noexcept {
186
+ return
187
+ lhs.label == rhs.label &&
188
+ lhs.file == rhs.file &&
189
+ lhs.first_lineno == rhs.first_lineno;
190
+ }
191
+
192
+ struct Frame {
193
+ VALUE frame;
194
+ int line;
195
+
196
+ FrameInfo info() const {
197
+ return FrameInfo(frame);
198
+ }
199
+ };
200
+
201
+ bool operator==(const Frame& lhs, const Frame& rhs) noexcept {
202
+ return lhs.frame == rhs.frame && lhs.line == rhs.line;
203
+ }
204
+
205
+ namespace std {
206
+ template<>
207
+ struct hash<Frame>
208
+ {
209
+ std::size_t operator()(Frame const& s) const noexcept
210
+ {
211
+ return s.frame ^ s.line;
212
+ }
213
+ };
214
+ }
215
+
152
216
  // A basic semaphore built on sem_wait/sem_post
153
217
  // post() is guaranteed to be async-signal-safe
154
218
  class SamplerSemaphore {
@@ -459,6 +523,8 @@ class BaseCollector {
459
523
  bool running = false;
460
524
  FrameList frame_list;
461
525
 
526
+ virtual ~BaseCollector() {}
527
+
462
528
  virtual bool start() {
463
529
  if (running) {
464
530
  return false;
@@ -666,7 +732,9 @@ class Thread {
666
732
  if (e != 0) rb_syserr_fail(e, "pthread_threadid_np");
667
733
  return thread_id;
668
734
  #else
669
- return gettid();
735
+ // gettid() is only available as of glibc 2.30
736
+ pid_t tid = syscall(SYS_gettid);
737
+ return tid;
670
738
  #endif
671
739
  }
672
740
 
@@ -817,7 +885,7 @@ class TimeCollector : public BaseCollector {
817
885
  atomic_bool running;
818
886
  SamplerSemaphore thread_stopped;
819
887
 
820
- static inline LiveSample *live_sample;
888
+ static LiveSample *live_sample;
821
889
 
822
890
  TimeStamp started_at;
823
891
  TimeStamp interval;
@@ -1097,6 +1165,8 @@ class TimeCollector : public BaseCollector {
1097
1165
  }
1098
1166
  };
1099
1167
 
1168
+ LiveSample *TimeCollector::live_sample;
1169
+
1100
1170
  static void
1101
1171
  collector_mark(void *data) {
1102
1172
  BaseCollector *collector = static_cast<BaseCollector *>(data);
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Vernier
4
- VERSION = "0.2.0"
4
+ VERSION = "0.2.1"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vernier
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Hawthorn
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-08-04 00:00:00.000000000 Z
11
+ date: 2023-08-08 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: An experimental profiler
14
14
  email:
@@ -28,7 +28,6 @@ files:
28
28
  - examples/threaded_http_requests.rb
29
29
  - ext/vernier/extconf.rb
30
30
  - ext/vernier/ruby_type_names.h
31
- - ext/vernier/stack.hh
32
31
  - ext/vernier/vernier.cc
33
32
  - ext/vernier/vernier.hh
34
33
  - lib/vernier.rb
data/ext/vernier/stack.hh DELETED
@@ -1,155 +0,0 @@
1
- #pragma once
2
-
3
- #include "ruby/debug.h"
4
-
5
- #include <iostream>
6
- #include <vector>
7
- #include <memory>
8
- #include <algorithm>
9
-
10
- struct FrameInfo {
11
- static const char *label_cstr(VALUE frame) {
12
- VALUE label = rb_profile_frame_full_label(frame);
13
- return StringValueCStr(label);
14
- }
15
-
16
- static const char *file_cstr(VALUE frame) {
17
- VALUE file = rb_profile_frame_absolute_path(frame);
18
- if (NIL_P(file))
19
- file = rb_profile_frame_path(frame);
20
- if (NIL_P(file)) {
21
- return "";
22
- } else {
23
- return StringValueCStr(file);
24
- }
25
- }
26
-
27
- static int first_lineno_int(VALUE frame) {
28
- VALUE first_lineno = rb_profile_frame_first_lineno(frame);
29
- return NIL_P(first_lineno) ? 0 : FIX2INT(first_lineno);
30
- }
31
-
32
- FrameInfo(VALUE frame) :
33
- label(label_cstr(frame)),
34
- file(file_cstr(frame)),
35
- first_lineno(first_lineno_int(frame)) { }
36
-
37
- std::string label;
38
- std::string file;
39
- int first_lineno;
40
- };
41
-
42
- bool operator==(const FrameInfo& lhs, const FrameInfo& rhs) noexcept {
43
- return
44
- lhs.label == rhs.label &&
45
- lhs.file == rhs.file &&
46
- lhs.first_lineno == rhs.first_lineno;
47
- }
48
-
49
- template<>
50
- struct std::hash<FrameInfo>
51
- {
52
- std::size_t operator()(FrameInfo const& f) const noexcept
53
- {
54
- return
55
- std::hash<std::string>{}(f.label) ^
56
- std::hash<std::string>{}(f.file) ^
57
- f.first_lineno;
58
- }
59
- };
60
-
61
-
62
- struct Frame {
63
- VALUE frame;
64
- int line;
65
-
66
- FrameInfo info() const {
67
- return FrameInfo(frame);
68
- }
69
- };
70
-
71
- bool operator==(const Frame& lhs, const Frame& rhs) noexcept {
72
- return lhs.frame == rhs.frame && lhs.line == rhs.line;
73
- }
74
-
75
- template<>
76
- struct std::hash<Frame>
77
- {
78
- std::size_t operator()(Frame const& s) const noexcept
79
- {
80
- return s.frame ^ s.line;
81
- }
82
- };
83
-
84
- struct BaseStack {
85
- virtual ~BaseStack() {};
86
-
87
- virtual int size() const = 0;
88
- };
89
-
90
- struct Stack : public BaseStack {
91
- std::unique_ptr<VALUE[]> frames;
92
- std::unique_ptr<int[]> lines;
93
- int _size = 0;
94
-
95
- int size() const {
96
- return _size;
97
- }
98
-
99
- Stack(const VALUE *_frames, const int *_lines, int size) :
100
- _size(size),
101
- frames(std::make_unique<VALUE[]>(size)),
102
- lines(std::make_unique<int[]>(size))
103
- {
104
- std::copy_n(_frames, size, &frames[0]);
105
- std::copy_n(_lines, size, &lines[0]);
106
- }
107
-
108
- Stack(const Stack &s) :
109
- _size(s.size()),
110
- frames(std::make_unique<VALUE[]>(s.size())),
111
- lines(std::make_unique<int[]>(s.size()))
112
- {
113
- std::copy_n(&s.frames[0], s.size(), &frames[0]);
114
- std::copy_n(&s.lines[0], s.size(), &lines[0]);
115
- }
116
-
117
- Frame frame(int i) const {
118
- if (i >= size()) throw std::out_of_range("nope");
119
- return Frame{frames[i], lines[i]};
120
- }
121
- };
122
-
123
- bool operator==(const Stack& lhs, const Stack& rhs) noexcept {
124
- return lhs.size() == rhs.size() &&
125
- std::equal(&lhs.frames[0], &lhs.frames[lhs.size()], &rhs.frames[0]) &&
126
- std::equal(&lhs.lines[0], &lhs.lines[lhs.size()], &rhs.lines[0]);
127
- }
128
-
129
- // https://xoshiro.di.unimi.it/splitmix64.c
130
- // https://nullprogram.com/blog/2018/07/31/
131
- uint64_t
132
- hash64(uint64_t x)
133
- {
134
- x ^= x >> 16;
135
- x *= 0x7feb352dU;
136
- x ^= x >> 15;
137
- x *= 0x846ca68bU;
138
- x ^= x >> 16;
139
- return x;
140
- }
141
-
142
- template<>
143
- struct std::hash<Stack>
144
- {
145
- std::size_t operator()(Stack const& s) const noexcept
146
- {
147
- size_t hash = 0;
148
- for (int i = 0; i < s.size(); i++) {
149
- VALUE frame = s.frames[i];
150
- hash ^= frame;
151
- hash = hash64(hash);
152
- }
153
- return hash;
154
- }
155
- };