ext/stackprof/stackprof.c in stackprof-0.2.15 vs ext/stackprof/stackprof.c in stackprof-0.2.16
- old
+ new
@@ -14,10 +14,11 @@
#include <signal.h>
#include <sys/time.h>
#include <pthread.h>
#define BUF_SIZE 2048
+#define MICROSECONDS_IN_SECOND 1000000
#define FAKE_FRAME_GC INT2FIX(0)
#define FAKE_FRAME_MARK INT2FIX(1)
#define FAKE_FRAME_SWEEP INT2FIX(2)
@@ -44,10 +45,11 @@
VALUE mode;
VALUE interval;
VALUE out;
VALUE metadata;
+ int ignore_gc;
VALUE *raw_samples;
size_t raw_samples_len;
size_t raw_samples_capa;
size_t raw_sample_index;
@@ -71,12 +73,12 @@
int lines_buffer[BUF_SIZE];
} _stackprof;
static VALUE sym_object, sym_wall, sym_cpu, sym_custom, sym_name, sym_file, sym_line;
static VALUE sym_samples, sym_total_samples, sym_missed_samples, sym_edges, sym_lines;
-static VALUE sym_version, sym_mode, sym_interval, sym_raw, sym_metadata, sym_frames, sym_out, sym_aggregate, sym_raw_timestamp_deltas;
-static VALUE sym_state, sym_marking, sym_sweeping;
+static VALUE sym_version, sym_mode, sym_interval, sym_raw, sym_metadata, sym_frames, sym_ignore_gc, sym_out;
+static VALUE sym_aggregate, sym_raw_timestamp_deltas, sym_state, sym_marking, sym_sweeping;
static VALUE sym_gc_samples, objtracer;
static VALUE gc_hook;
static VALUE rb_mStackProf;
static void stackprof_newobj_handler(VALUE, void*);
@@ -86,10 +88,11 @@
stackprof_start(int argc, VALUE *argv, VALUE self)
{
struct sigaction sa;
struct itimerval timer;
VALUE opts = Qnil, mode = Qnil, interval = Qnil, metadata = rb_hash_new(), out = Qfalse;
+ int ignore_gc = 0;
int raw = 0, aggregate = 1;
if (_stackprof.running)
return Qfalse;
@@ -97,10 +100,13 @@
if (RTEST(opts)) {
mode = rb_hash_aref(opts, sym_mode);
interval = rb_hash_aref(opts, sym_interval);
out = rb_hash_aref(opts, sym_out);
+ if (RTEST(rb_hash_aref(opts, sym_ignore_gc))) {
+ ignore_gc = 1;
+ }
VALUE metadata_val = rb_hash_aref(opts, sym_metadata);
if (RTEST(metadata_val)) {
if (!RB_TYPE_P(metadata_val, T_HASH))
rb_raise(rb_eArgError, "metadata should be a hash");
@@ -113,10 +119,14 @@
if (rb_hash_lookup2(opts, sym_aggregate, Qundef) == Qfalse)
aggregate = 0;
}
if (!RTEST(mode)) mode = sym_wall;
+ if (!NIL_P(interval) && (NUM2INT(interval) < 1 || NUM2INT(interval) >= MICROSECONDS_IN_SECOND)) {
+ rb_raise(rb_eArgError, "interval is a number of microseconds between 1 and 1 million");
+ }
+
if (!_stackprof.frames) {
_stackprof.frames = st_init_numtable();
_stackprof.overall_signals = 0;
_stackprof.overall_samples = 0;
_stackprof.during_gc = 0;
@@ -149,10 +159,11 @@
_stackprof.running = 1;
_stackprof.raw = raw;
_stackprof.aggregate = aggregate;
_stackprof.mode = mode;
_stackprof.interval = interval;
+ _stackprof.ignore_gc = ignore_gc;
_stackprof.metadata = metadata;
_stackprof.out = out;
if (raw) {
gettimeofday(&_stackprof.last_sample_at, NULL);
@@ -608,11 +619,11 @@
static void
stackprof_signal_handler(int sig, siginfo_t *sinfo, void *ucontext)
{
_stackprof.overall_signals++;
- if (rb_during_gc()) {
+ if (!_stackprof.ignore_gc && rb_during_gc()) {
VALUE mode = rb_gc_latest_gc_info(sym_state);
if (mode == sym_marking) {
_stackprof.unrecorded_gc_marking_samples++;
} else if (mode == sym_sweeping) {
_stackprof.unrecorded_gc_sweeping_samples++;
@@ -720,9 +731,10 @@
S(interval);
S(raw);
S(raw_timestamp_deltas);
S(out);
S(metadata);
+ S(ignore_gc);
S(frames);
S(aggregate);
S(state);
S(marking);
S(sweeping);