Module: FastStack

Defined in:
lib/fast_stack.rb,
ext/fast_stack/fast_stack.c

Class Method Summary collapse

Class Method Details

.profile(millisecs = 1, &blk) ⇒ Object



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/fast_stack.rb', line 3

def self.profile(millisecs=1, &blk)
  stacks = []
  thread = Thread.current
  last_time = Time.new

  new_api = thread.respond_to?(:backtrace_locations)

  trap('ALRM') do
    FastStack.stop
    stack = (new_api ? thread.backtrace_locations : thread.backtrace)
    # I am not sure if this is ensured to run in the thread
    # though in my samples it always does
    if thread == Thread.current
      stack = stack[2..-1]
    end
    stacks << stack
    FastStack.start(millisecs * 1000)
  end

  profile_block(millisecs * 1000, &blk)

  stacks
end

.profile_block(usec) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
# File 'ext/fast_stack/fast_stack.c', line 28

static VALUE
rb_profile_block(VALUE module, VALUE usec)
{
    rb_need_block();

    rb_profile_start(module, usec);
    rb_yield(Qundef);
    rb_profile_stop(module);

    return Qnil;
}

.start(usec) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
# File 'ext/fast_stack/fast_stack.c', line 6

static VALUE
rb_profile_start(VALUE module, VALUE usec)
{
    struct itimerval timer;
    timer.it_interval.tv_sec = 0;
    timer.it_interval.tv_usec = (suseconds_t)NUM2LONG(usec);
    timer.it_value = timer.it_interval;
    setitimer(ITIMER_REAL, &timer, 0);

    return Qnil;
}

.stopObject



18
19
20
21
22
23
24
25
26
# File 'ext/fast_stack/fast_stack.c', line 18

static VALUE
rb_profile_stop(VALUE module)
{
    struct itimerval timer;
    memset(&timer, 0, sizeof(timer));
    setitimer(ITIMER_REAL, &timer, 0);

    return Qnil;
}