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);