Class: RbBCC::RingBuf

Inherits:
TableBase show all
Includes:
EventTypeSupported
Defined in:
lib/rbbcc/table.rb

Instance Attribute Summary

Attributes inherited from TableBase

#bpf, #flags, #keysize, #keytype, #leafsize, #leaftype, #map_fd, #map_id, #name, #ttype

Class Method Summary collapse

Instance Method Summary collapse

Methods included from EventTypeSupported

#get_event_class

Methods inherited from TableBase

#[], #[]=, #clear, #delete, #each_key, #each_pair, #each_value, #fetch, #items, #next, #pin!, #print_linear_hist, #print_log2_hist, #structured_key?, #values

Methods included from CPUHelper

_read_cpu_range, get_online_cpus, get_possible_cpus

Constructor Details

#initialize(bpf, map_id, map_fd, keytype, leaftype, name: nil) ⇒ RingBuf

Returns a new instance of RingBuf.



461
462
463
464
465
466
# File 'lib/rbbcc/table.rb', line 461

def initialize(bpf, map_id, map_fd, keytype, leaftype, name: nil)
  super
  @_ringbuf = nil
  @_ringbuf_manager = nil
  @event_class = nil
end

Class Method Details

.from_pin(path, leaftype, size, name: "events") ⇒ Object

Make a dynamic BCC program to load the pinned ringbuf map



441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
# File 'lib/rbbcc/table.rb', line 441

def self.from_pin(path, leaftype, size, name: "events")
  map_fd = Clib.bpf_obj_get(path)
  if map_fd < 0
    raise SystemCallError.new("Could not open pinned map", Fiddle.last_error)
  end
  leaftype_typename = case leaftype
  when /\Astruct\s+(\w+)\s+{/m
    "struct #{Regexp.last_match(1)}"
  else
    leaftype
  end
  
  prog = <<~CLANG
    #{leaftype}
    BPF_TABLE_PINNED("ringbuf", u32, #{leaftype_typename}, #{name}, #{size}, "#{path}");
  CLANG
  b = BCC.new(text: prog)
  b[name.to_s]
end

Instance Method Details

#event(data) ⇒ Object



468
469
470
471
472
473
# File 'lib/rbbcc/table.rb', line 468

def event(data)
  @event_class ||= (get_event_class || self.leaftype)
  ev = @event_class.malloc
  Fiddle::Pointer.new(ev.to_ptr)[0, @event_class.size] = data[0, @event_class.size]
  return ev
end

#open_ring_buffer(ctx = nil, &callback) ⇒ Object



475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
# File 'lib/rbbcc/table.rb', line 475

def open_ring_buffer(ctx=nil, &callback)
  # bind("int ring_buffer_sample_fn(void *, void *, int)")
  fn = Fiddle::Closure::BlockCaller.new(
    Fiddle::TYPE_INT,
    [Fiddle::TYPE_VOIDP, Fiddle::TYPE_VOIDP, Fiddle::TYPE_INT]
  ) do |_dummy, data, size|
    begin
      _ret = callback.call(ctx, data, size)
      ret = _ret.to_i
      ret
    rescue NoMethodError
      # Callback for ringbufs should _always_ return an integer.
      # simply fall back to returning 0 when failed
      0
    rescue => e
      if Fiddle.last_error == 32 # EPIPE
        exit
      else
        raise e
      end
    end
  end

  @bpf._open_ring_buffer(@map_fd, fn, ctx)
  nil
end

#ring_buffer_poll(timeout = -1)) ⇒ Object



502
503
504
# File 'lib/rbbcc/table.rb', line 502

def ring_buffer_poll(timeout=-1)
  @bpf.ring_buffer_poll(timeout)
end