class RbBCC::PerfEventArray
Public Class Methods
new(bpf, map_id, map_fd, keytype, leaftype, name: nil)
click to toggle source
Calls superclass method
RbBCC::TableBase::new
# File lib/rbbcc/table.rb, line 263 def initialize(bpf, map_id, map_fd, keytype, leaftype, name: nil) super @open_key_fds = {} @event_class = nil @_cbs = {} @_open_key_fds = {} end
Public Instance Methods
event(data)
click to toggle source
# File lib/rbbcc/table.rb, line 271 def event(data) @event_class ||= get_event_class ev = @event_class.malloc Fiddle::Pointer.new(ev.to_ptr)[0, @event_class.size] = data[0, @event_class.size] return ev end
open_perf_buffer(page_cnt: 8, lost_cb: nil, &callback)
click to toggle source
# File lib/rbbcc/table.rb, line 278 def open_perf_buffer(page_cnt: 8, lost_cb: nil, &callback) if page_cnt & (page_cnt - 1) != 0 raise "Perf buffer page_cnt must be a power of two" end get_online_cpus.each do |i| _open_perf_buffer(i, callback, page_cnt, lost_cb) end end
Private Instance Methods
_open_perf_buffer(cpu, callback, page_cnt, lost_cb)
click to toggle source
# File lib/rbbcc/table.rb, line 342 def _open_perf_buffer(cpu, callback, page_cnt, lost_cb) # bind("void raw_cb_callback(void *, void *, int)") fn = Fiddle::Closure::BlockCaller.new( Fiddle::TYPE_VOID, [Fiddle::TYPE_VOIDP, Fiddle::TYPE_VOIDP, Fiddle::TYPE_INT] ) do |_dummy, data, size| begin callback.call(cpu, data, size) rescue => e if Fiddle.last_error == 32 # EPIPE exit else raise e end end end lost_fn = Fiddle::Closure::BlockCaller.new( Fiddle::TYPE_VOID, [Fiddle::TYPE_VOIDP, Fiddle::TYPE_ULONG] ) do |_dummy, lost| begin lost_cb(lost) rescue => e if Fiddle.last_error == 32 # EPIPE exit else raise e end end end if lost_cb reader = Clib.bpf_open_perf_buffer(fn, lost_fn, nil, -1, cpu, page_cnt) if !reader || reader.null? raise "Could not open perf buffer" end fd = Clib.perf_reader_fd(reader) self[byref(cpu, @keysize)] = byref(fd, @leafsize) self.bpf.perf_buffers[[object_id, cpu]] = reader @_cbs[cpu] = [fn, lost_fn] @_open_key_fds[cpu] = -1 end
get_event_class()
click to toggle source
Calls superclass method
# File lib/rbbcc/table.rb, line 289 def get_event_class ct_mapping = { 's8': 'char', 'u8': 'unsined char', 's8 *': 'char *', 's16': 'short', 'u16': 'unsigned short', 's32': 'int', 'u32': 'unsigned int', 's64': 'long long', 'u64': 'unsigned long long' } array_type = /(.+) \[([0-9]+)\]$/ fields = [] num_fields = Clib.bpf_perf_event_fields(self.bpf.module, @name) num_fields.times do |i| field = Clib.__extract_char(Clib.bpf_perf_event_field(self.bpf.module, @name, i)) field_name, field_type = *field.split('#') if field_type =~ /enum .*/ field_type = "int" #it is indeed enum... end if _field_type = ct_mapping[field_type.to_sym] field_type = _field_type end m = array_type.match(field_type) if m field_type = "#{m[1]}[#{m[2]}]" fields << [field_type, field_name].join(" ") else fields << [field_type, field_name].join(" ") end end klass = Fiddle::Importer.struct(fields) char_ps = fields.select {|f| f =~ /^char\[(\d+)\] ([_a-zA-Z0-9]+)/ } unless char_ps.empty? m = Module.new do char_ps.each do |char_p| md = /^char\[(\d+)\] ([_a-zA-Z0-9]+)/.match(char_p) define_method md[2] do # Split the char[] in the place where the first \0 appears raw = super() raw = raw[0...raw.index(0)] if raw.index(0) raw.pack("c*") end end end klass.prepend m end klass end