gvl-tracing 1.5.2 → 1.6.1
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
- data/README.adoc +7 -1
- data/ext/gvl_tracing_native_extension/gvl_tracing.c +112 -28
- data/gvl-tracing.gemspec +2 -1
- data/lib/gvl-tracing.rb +2 -2
- data/lib/gvl_tracing/sleep_tracking.rb +1 -1
- data/lib/gvl_tracing/version.rb +1 -1
- data/preview.png +0 -0
- metadata +3 -8
- data/.editorconfig +0 -22
- data/.ruby-version +0 -1
- data/.standard.yml +0 -9
- data/Rakefile +0 -36
- data/gems.rb +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2bf28c6665bf4afa02c13299947bb65d7c62c3af783858afdc3a5383e334fa47
|
4
|
+
data.tar.gz: b1999e7e17d56e76ba732962708c14979e2690cd78204946d2f05e7146b05725
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: feb5fb173e07343af18c929608b20b2463fc0b676565b926242585f3fed31991e34ab5f549d7cbfe0e26c883d4a1e6eebf1d8da9e1586f0fa63d0890cdd3b108
|
7
|
+
data.tar.gz: 615226e345e230b989d7738754f02a058935d67679b4ca16c610cbbb6fe34f82aff6de3299d9548af579a30d55bccaedf25cd52d4f631023cff93a683fe3c8bb
|
data/README.adoc
CHANGED
@@ -25,7 +25,7 @@ def fib(n)
|
|
25
25
|
fib(n - 1) + fib(n - 2)
|
26
26
|
end
|
27
27
|
|
28
|
-
GvlTracing.start("example1.json") do
|
28
|
+
GvlTracing.start("example1.json", os_threads_view_enabled: false) do
|
29
29
|
Thread.new { sleep(0.05) while true }
|
30
30
|
|
31
31
|
sleep(0.05)
|
@@ -68,6 +68,12 @@ This gem only provides a single module (`GvlTracing`) with methods:
|
|
68
68
|
|
69
69
|
The resulting traces can be analyzed by going to https://ui.perfetto.dev/[Perfetto UI].
|
70
70
|
|
71
|
+
== Experimental features
|
72
|
+
|
73
|
+
1. Sleep tracking: Add `require 'gvl_tracing/sleep_tracking'` to add a more specific `sleeping` state for sleeps (which are otherwise rendered as `waiting` without this feature)
|
74
|
+
|
75
|
+
2. OS threads view: Pass in `os_threads_view_enabled: true` to `GvlTracing.start` to also render a view of Ruby thread activity from the OS native threads point-of-view. This is useful when using M:N thread scheduling, which is used on Ruby 3.3+ Ractors, and when using the `RUBY_MN_THREADS=1` setting.
|
76
|
+
|
71
77
|
== Tips
|
72
78
|
|
73
79
|
You can "embed" links to the perfetto UI which trigger loading of a trace by following the instructions on https://perfetto.dev/docs/visualization/deep-linking-to-perfetto-ui .
|
@@ -32,6 +32,7 @@
|
|
32
32
|
#include <stdbool.h>
|
33
33
|
#include <sys/types.h>
|
34
34
|
#include <pthread.h>
|
35
|
+
#include <stdint.h>
|
35
36
|
|
36
37
|
#include "extconf.h"
|
37
38
|
|
@@ -56,6 +57,10 @@
|
|
56
57
|
#define RUBY_3_2
|
57
58
|
#endif
|
58
59
|
|
60
|
+
// For the OS threads view, we emit data as if it was for another pid so it gets grouped separately in perfetto.
|
61
|
+
// This is a really big hack, but I couldn't think of a better way?
|
62
|
+
#define OS_THREADS_VIEW_PID (INT64_C(0))
|
63
|
+
|
59
64
|
typedef struct {
|
60
65
|
bool initialized;
|
61
66
|
int32_t current_thread_serial;
|
@@ -78,20 +83,27 @@ static VALUE gc_tracepoint = Qnil;
|
|
78
83
|
static int thread_storage_key = 0;
|
79
84
|
static VALUE all_seen_threads = Qnil;
|
80
85
|
static pthread_mutex_t all_seen_threads_mutex = PTHREAD_MUTEX_INITIALIZER;
|
86
|
+
static pthread_mutex_t output_mutex = PTHREAD_MUTEX_INITIALIZER;
|
87
|
+
static bool os_threads_view_enabled;
|
81
88
|
|
82
89
|
static VALUE tracing_init_local_storage(VALUE, VALUE);
|
83
|
-
static VALUE tracing_start(VALUE _self, VALUE output_path);
|
90
|
+
static VALUE tracing_start(UNUSED_ARG VALUE _self, VALUE output_path, VALUE os_threads_view_enabled_arg);
|
84
91
|
static VALUE tracing_stop(VALUE _self);
|
85
92
|
static double timestamp_microseconds(void);
|
86
|
-
static
|
93
|
+
static double render_event(thread_local_state *, const char *event_name);
|
87
94
|
static void on_thread_event(rb_event_flag_t event, const rb_internal_thread_event_data_t *_unused1, void *_unused2);
|
88
95
|
static void on_gc_event(VALUE tpval, void *_unused1);
|
89
96
|
static VALUE mark_sleeping(VALUE _self);
|
90
97
|
static size_t thread_local_state_memsize(UNUSED_ARG const void *_unused);
|
91
98
|
static void thread_local_state_mark(void *data);
|
99
|
+
static inline void output_mutex_lock(void);
|
100
|
+
static inline void output_mutex_unlock(void);
|
92
101
|
static inline int32_t thread_id_for(thread_local_state *state);
|
93
102
|
static VALUE ruby_thread_id_for(UNUSED_ARG VALUE _self, VALUE thread);
|
94
103
|
static VALUE trim_all_seen_threads(UNUSED_ARG VALUE _self);
|
104
|
+
static void render_os_thread_event(thread_local_state *state, double now_microseconds);
|
105
|
+
static void finish_previous_os_thread_event(double now_microseconds);
|
106
|
+
static inline uint32_t current_native_thread_id(void);
|
95
107
|
|
96
108
|
#pragma GCC diagnostic ignored "-Wunused-const-variable"
|
97
109
|
static const rb_data_type_t thread_local_state_type = {
|
@@ -131,7 +143,7 @@ void Init_gvl_tracing_native_extension(void) {
|
|
131
143
|
VALUE gvl_tracing_module = rb_define_module("GvlTracing");
|
132
144
|
|
133
145
|
rb_define_singleton_method(gvl_tracing_module, "_init_local_storage", tracing_init_local_storage, 1);
|
134
|
-
rb_define_singleton_method(gvl_tracing_module, "_start", tracing_start,
|
146
|
+
rb_define_singleton_method(gvl_tracing_module, "_start", tracing_start, 2);
|
135
147
|
rb_define_singleton_method(gvl_tracing_module, "_stop", tracing_stop, 0);
|
136
148
|
rb_define_singleton_method(gvl_tracing_module, "mark_sleeping", mark_sleeping, 0);
|
137
149
|
rb_define_singleton_method(gvl_tracing_module, "_thread_id_for", ruby_thread_id_for, 1);
|
@@ -143,24 +155,7 @@ static inline void initialize_thread_local_state(thread_local_state *state) {
|
|
143
155
|
state->current_thread_serial = RUBY_ATOMIC_FETCH_ADD(thread_serial, 1);
|
144
156
|
|
145
157
|
#ifdef RUBY_3_2
|
146
|
-
|
147
|
-
|
148
|
-
#ifdef HAVE_PTHREAD_THREADID_NP
|
149
|
-
uint64_t full_native_thread_id;
|
150
|
-
pthread_threadid_np(pthread_self(), &full_native_thread_id);
|
151
|
-
// Note: `pthread_threadid_np` is declared as taking in a `uint64_t` but I don't think macOS uses such really
|
152
|
-
// high thread ids, and anyway perfetto doesn't like full 64-bit ids for threads so let's go with a simplification
|
153
|
-
// for now.
|
154
|
-
native_thread_id = (uint32_t) full_native_thread_id;
|
155
|
-
#elif HAVE_GETTID
|
156
|
-
native_thread_id = gettid();
|
157
|
-
#else
|
158
|
-
// Note: We could use the current_thread_serial as a crappy fallback, but this would make getting thread names
|
159
|
-
// not work very well
|
160
|
-
#error No native thread id available?
|
161
|
-
#endif
|
162
|
-
|
163
|
-
state->native_thread_id = native_thread_id;
|
158
|
+
state->native_thread_id = current_native_thread_id();
|
164
159
|
#endif
|
165
160
|
}
|
166
161
|
|
@@ -174,8 +169,9 @@ static VALUE tracing_init_local_storage(UNUSED_ARG VALUE _self, VALUE threads) {
|
|
174
169
|
return Qtrue;
|
175
170
|
}
|
176
171
|
|
177
|
-
static VALUE tracing_start(UNUSED_ARG VALUE _self, VALUE output_path) {
|
172
|
+
static VALUE tracing_start(UNUSED_ARG VALUE _self, VALUE output_path, VALUE os_threads_view_enabled_arg) {
|
178
173
|
Check_Type(output_path, T_STRING);
|
174
|
+
if (os_threads_view_enabled_arg != Qtrue && os_threads_view_enabled_arg != Qfalse) rb_raise(rb_eArgError, "os_threads_view_enabled must be true/false");
|
179
175
|
|
180
176
|
trim_all_seen_threads(Qnil);
|
181
177
|
|
@@ -183,13 +179,26 @@ static VALUE tracing_start(UNUSED_ARG VALUE _self, VALUE output_path) {
|
|
183
179
|
output_file = fopen(StringValuePtr(output_path), "w");
|
184
180
|
if (output_file == NULL) rb_syserr_fail(errno, "Failed to open GvlTracing output file");
|
185
181
|
|
186
|
-
fprintf(output_file, "[\n");
|
187
|
-
|
188
182
|
thread_local_state *state = GT_CURRENT_THREAD_LOCAL_STATE();
|
189
183
|
started_tracing_at_microseconds = timestamp_microseconds();
|
190
184
|
process_id = getpid();
|
185
|
+
os_threads_view_enabled = (os_threads_view_enabled_arg == Qtrue);
|
186
|
+
|
187
|
+
VALUE ruby_version = rb_const_get(rb_cObject, rb_intern("RUBY_VERSION"));
|
188
|
+
Check_Type(ruby_version, T_STRING);
|
189
|
+
|
190
|
+
fprintf(output_file, "[\n");
|
191
|
+
fprintf(output_file,
|
192
|
+
" {\"ph\": \"M\", \"pid\": %"PRId64", \"name\": \"process_name\", \"args\": {\"name\": \"Ruby threads view (%s)\"}},\n",
|
193
|
+
process_id, StringValuePtr(ruby_version)
|
194
|
+
);
|
195
|
+
|
196
|
+
double now_microseconds = render_event(state, "started_tracing");
|
191
197
|
|
192
|
-
|
198
|
+
if (os_threads_view_enabled) {
|
199
|
+
fprintf(output_file, " {\"ph\": \"M\", \"pid\": %"PRId64", \"name\": \"process_name\", \"args\": {\"name\": \"OS threads view\"}},\n", OS_THREADS_VIEW_PID);
|
200
|
+
render_os_thread_event(state, now_microseconds);
|
201
|
+
}
|
193
202
|
|
194
203
|
current_hook = rb_internal_thread_add_event_hook(
|
195
204
|
on_thread_event,
|
@@ -218,7 +227,9 @@ static VALUE tracing_stop(UNUSED_ARG VALUE _self) {
|
|
218
227
|
rb_tracepoint_disable(gc_tracepoint);
|
219
228
|
gc_tracepoint = Qnil;
|
220
229
|
|
221
|
-
render_event(state, "stopped_tracing");
|
230
|
+
double now_microseconds = render_event(state, "stopped_tracing");
|
231
|
+
if (os_threads_view_enabled) finish_previous_os_thread_event(now_microseconds);
|
232
|
+
|
222
233
|
// closing the json syntax in the output file is handled in GvlTracing.stop code
|
223
234
|
|
224
235
|
if (fclose(output_file) != 0) rb_syserr_fail(errno, "Failed to close GvlTracing output file");
|
@@ -240,7 +251,7 @@ static double timestamp_microseconds(void) {
|
|
240
251
|
|
241
252
|
// Render output using trace event format for perfetto:
|
242
253
|
// https://chromium.googlesource.com/catapult/+/refs/heads/main/docs/trace-event-format.md
|
243
|
-
static
|
254
|
+
static double render_event(thread_local_state *state, const char *event_name) {
|
244
255
|
// Event data
|
245
256
|
double now_microseconds = timestamp_microseconds() - started_tracing_at_microseconds;
|
246
257
|
|
@@ -251,6 +262,7 @@ static void render_event(thread_local_state *state, const char *event_name) {
|
|
251
262
|
// Important note: We've observed some rendering issues in perfetto if the tid or pid are numbers that are "too big",
|
252
263
|
// see https://github.com/ivoanjo/gvl-tracing/pull/4#issuecomment-1196463364 for an example.
|
253
264
|
|
265
|
+
output_mutex_lock();
|
254
266
|
fprintf(output_file,
|
255
267
|
// Finish previous duration
|
256
268
|
" {\"ph\": \"E\", \"pid\": %"PRId64", \"tid\": %d, \"ts\": %f},\n" \
|
@@ -261,6 +273,9 @@ static void render_event(thread_local_state *state, const char *event_name) {
|
|
261
273
|
// Args for second line
|
262
274
|
process_id, thread_id_for(state), now_microseconds, event_name
|
263
275
|
);
|
276
|
+
output_mutex_unlock();
|
277
|
+
|
278
|
+
return now_microseconds;
|
264
279
|
}
|
265
280
|
|
266
281
|
static void on_thread_event(rb_event_flag_t event_id, const rb_internal_thread_event_data_t *event_data, UNUSED_ARG void *_unused2) {
|
@@ -298,7 +313,15 @@ static void on_thread_event(rb_event_flag_t event_id, const rb_internal_thread_e
|
|
298
313
|
case RUBY_INTERNAL_THREAD_EVENT_STARTED: event_name = "started"; break;
|
299
314
|
case RUBY_INTERNAL_THREAD_EVENT_EXITED: event_name = "died"; break;
|
300
315
|
};
|
301
|
-
render_event(state, event_name);
|
316
|
+
double now_microseconds = render_event(state, event_name);
|
317
|
+
|
318
|
+
if (os_threads_view_enabled) {
|
319
|
+
if (event_id == RUBY_INTERNAL_THREAD_EVENT_RESUMED) {
|
320
|
+
render_os_thread_event(state, now_microseconds);
|
321
|
+
} else if (event_id == RUBY_INTERNAL_THREAD_EVENT_SUSPENDED || event_id == RUBY_INTERNAL_THREAD_EVENT_EXITED) {
|
322
|
+
finish_previous_os_thread_event(now_microseconds);
|
323
|
+
}
|
324
|
+
}
|
302
325
|
}
|
303
326
|
|
304
327
|
static void on_gc_event(VALUE tpval, UNUSED_ARG void *_unused1) {
|
@@ -337,6 +360,18 @@ static inline void all_seen_threads_mutex_unlock(void) {
|
|
337
360
|
if (error) rb_syserr_fail(error, "Failed to unlock GvlTracing mutex");
|
338
361
|
}
|
339
362
|
|
363
|
+
static inline void output_mutex_lock(void) {
|
364
|
+
int error = pthread_mutex_lock(&output_mutex);
|
365
|
+
// Can't raise exceptions on error since it gets used from outside the GVL
|
366
|
+
if (error) fprintf(stderr, "Failed to lock the GvlTracing output_mutex");
|
367
|
+
}
|
368
|
+
|
369
|
+
static inline void output_mutex_unlock(void) {
|
370
|
+
int error = pthread_mutex_unlock(&output_mutex);
|
371
|
+
// Can't raise exceptions on error since it gets used from outside the GVL
|
372
|
+
if (error) fprintf(stderr, "Failed to unlock the GvlTracing output_mutex");
|
373
|
+
}
|
374
|
+
|
340
375
|
#ifdef RUBY_3_3_PLUS
|
341
376
|
static inline thread_local_state *GT_LOCAL_STATE(VALUE thread, bool allocate) {
|
342
377
|
thread_local_state *state = rb_internal_thread_specific_get(thread, thread_storage_key);
|
@@ -414,3 +449,52 @@ static VALUE trim_all_seen_threads(UNUSED_ARG VALUE _self) {
|
|
414
449
|
all_seen_threads_mutex_unlock();
|
415
450
|
return Qtrue;
|
416
451
|
}
|
452
|
+
|
453
|
+
// Creates an event that follows the current native thread. Note that this assumes that whatever event
|
454
|
+
// made us call `render_os_thread_event` is an event about the current (native) thread; if the event is not about the
|
455
|
+
// current thread, the results will be incorrect.
|
456
|
+
static void render_os_thread_event(thread_local_state *state, double now_microseconds) {
|
457
|
+
finish_previous_os_thread_event(now_microseconds);
|
458
|
+
|
459
|
+
// Hack: If we name threads as "Thread N", perfetto seems to color them all with the same color, which looks awful.
|
460
|
+
// I did not check the code, but in practice perfetto seems to be doing some kind of hashing based only on regular
|
461
|
+
// chars, so here we append a different letter to each thread to cause the color hashing to differ.
|
462
|
+
char color_suffix_hack = ('a' + (thread_id_for(state) % 26));
|
463
|
+
|
464
|
+
output_mutex_lock();
|
465
|
+
fprintf(output_file,
|
466
|
+
" {\"ph\": \"B\", \"pid\": %"PRId64", \"tid\": %u, \"ts\": %f, \"name\": \"Thread %d (%c)\"},\n",
|
467
|
+
OS_THREADS_VIEW_PID, current_native_thread_id(), now_microseconds, thread_id_for(state), color_suffix_hack
|
468
|
+
);
|
469
|
+
output_mutex_unlock();
|
470
|
+
}
|
471
|
+
|
472
|
+
static void finish_previous_os_thread_event(double now_microseconds) {
|
473
|
+
output_mutex_lock();
|
474
|
+
fprintf(output_file,
|
475
|
+
" {\"ph\": \"E\", \"pid\": %"PRId64", \"tid\": %u, \"ts\": %f},\n",
|
476
|
+
OS_THREADS_VIEW_PID, current_native_thread_id(), now_microseconds
|
477
|
+
);
|
478
|
+
output_mutex_unlock();
|
479
|
+
}
|
480
|
+
|
481
|
+
static inline uint32_t current_native_thread_id(void) {
|
482
|
+
uint32_t native_thread_id = 0;
|
483
|
+
|
484
|
+
#ifdef HAVE_PTHREAD_THREADID_NP
|
485
|
+
uint64_t full_native_thread_id;
|
486
|
+
pthread_threadid_np(pthread_self(), &full_native_thread_id);
|
487
|
+
// Note: `pthread_threadid_np` is declared as taking in a `uint64_t` but I don't think macOS uses such really
|
488
|
+
// high thread ids, and anyway perfetto doesn't like full 64-bit ids for threads so let's go with a simplification
|
489
|
+
// for now.
|
490
|
+
native_thread_id = (uint32_t) full_native_thread_id;
|
491
|
+
#elif HAVE_GETTID
|
492
|
+
native_thread_id = gettid();
|
493
|
+
#else
|
494
|
+
// Note: We could use a native thread-local crappy fallback, but I think the two above alternatives are available
|
495
|
+
// on all OSs that support the GVL tracing API.
|
496
|
+
#error No native thread id available?
|
497
|
+
#endif
|
498
|
+
|
499
|
+
return native_thread_id;
|
500
|
+
}
|
data/gvl-tracing.gemspec
CHANGED
@@ -42,7 +42,8 @@ Gem::Specification.new do |spec|
|
|
42
42
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
43
43
|
spec.files = Dir.chdir(__dir__) do
|
44
44
|
`git ls-files -z`.split("\x0").reject do |f|
|
45
|
-
(f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features|examples)/|\.(?:git|travis|circleci)|appveyor)})
|
45
|
+
(f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features|examples)/|\.(?:git|travis|circleci)|appveyor)}) ||
|
46
|
+
[".editorconfig", ".ruby-version", ".standard.yml", "gems.rb", "Rakefile"].include?(f)
|
46
47
|
end
|
47
48
|
end
|
48
49
|
spec.require_paths = ["lib", "ext"]
|
data/lib/gvl-tracing.rb
CHANGED
data/lib/gvl_tracing/version.rb
CHANGED
data/preview.png
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gvl-tracing
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.6.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ivo Anjo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-12-08 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email:
|
@@ -18,16 +18,11 @@ extensions:
|
|
18
18
|
- ext/gvl_tracing_native_extension/extconf.rb
|
19
19
|
extra_rdoc_files: []
|
20
20
|
files:
|
21
|
-
- ".editorconfig"
|
22
|
-
- ".ruby-version"
|
23
|
-
- ".standard.yml"
|
24
21
|
- CODE_OF_CONDUCT.adoc
|
25
22
|
- LICENSE
|
26
23
|
- README.adoc
|
27
|
-
- Rakefile
|
28
24
|
- ext/gvl_tracing_native_extension/extconf.rb
|
29
25
|
- ext/gvl_tracing_native_extension/gvl_tracing.c
|
30
|
-
- gems.rb
|
31
26
|
- gvl-tracing.gemspec
|
32
27
|
- lib/gvl-tracing.rb
|
33
28
|
- lib/gvl_tracing/sleep_tracking.rb
|
@@ -53,7 +48,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
53
48
|
- !ruby/object:Gem::Version
|
54
49
|
version: '0'
|
55
50
|
requirements: []
|
56
|
-
rubygems_version: 3.
|
51
|
+
rubygems_version: 3.4.1
|
57
52
|
signing_key:
|
58
53
|
specification_version: 4
|
59
54
|
summary: Get a timeline view of Global VM Lock usage in your Ruby app
|
data/.editorconfig
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
# EditorConfig is awesome: https://EditorConfig.org
|
2
|
-
|
3
|
-
# top-most EditorConfig file
|
4
|
-
root = true
|
5
|
-
|
6
|
-
# Unix-style newlines with a newline ending every file
|
7
|
-
[*]
|
8
|
-
end_of_line = lf
|
9
|
-
insert_final_newline = true
|
10
|
-
trim_trailing_whitespace = true
|
11
|
-
|
12
|
-
[*.h]
|
13
|
-
indent_style = space
|
14
|
-
indent_size = 2
|
15
|
-
|
16
|
-
[*.c]
|
17
|
-
indent_style = space
|
18
|
-
indent_size = 2
|
19
|
-
|
20
|
-
[*.yml]
|
21
|
-
indent_style = space
|
22
|
-
indent_size = 2
|
data/.ruby-version
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
ruby-3.2.2
|
data/.standard.yml
DELETED
data/Rakefile
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
# gvl-tracing: Ruby gem for getting a timelinew view of GVL usage
|
2
|
-
# Copyright (c) 2022 Ivo Anjo <ivo@ivoanjo.me>
|
3
|
-
#
|
4
|
-
# This file is part of gvl-tracing.
|
5
|
-
#
|
6
|
-
# MIT License
|
7
|
-
#
|
8
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
9
|
-
# of this software and associated documentation files (the "Software"), to deal
|
10
|
-
# in the Software without restriction, including without limitation the rights
|
11
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
12
|
-
# copies of the Software, and to permit persons to whom the Software is
|
13
|
-
# furnished to do so, subject to the following conditions:
|
14
|
-
#
|
15
|
-
# The above copyright notice and this permission notice shall be included in all
|
16
|
-
# copies or substantial portions of the Software.
|
17
|
-
#
|
18
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
19
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
20
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
21
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
22
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
23
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
24
|
-
# SOFTWARE.
|
25
|
-
|
26
|
-
# frozen_string_literal: true
|
27
|
-
|
28
|
-
require "bundler/gem_tasks"
|
29
|
-
require "standard/rake"
|
30
|
-
require "rake/extensiontask"
|
31
|
-
require "rspec/core/rake_task"
|
32
|
-
|
33
|
-
Rake::ExtensionTask.new("gvl_tracing_native_extension")
|
34
|
-
RSpec::Core::RakeTask.new(:spec)
|
35
|
-
|
36
|
-
task default: [:compile, :"standard:fix", :spec]
|
data/gems.rb
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
source "https://rubygems.org"
|
4
|
-
|
5
|
-
gemspec
|
6
|
-
|
7
|
-
gem "rake", "~> 13.0"
|
8
|
-
gem "rake-compiler", "~> 1.2"
|
9
|
-
gem "pry"
|
10
|
-
gem "pry-byebug"
|
11
|
-
gem "rspec"
|
12
|
-
gem "standard", "~> 1.33"
|
13
|
-
gem "concurrent-ruby"
|
14
|
-
gem "benchmark-ips", "~> 2.13"
|