Class: RbBCC::PerfEventArray

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

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, #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) ⇒ PerfEventArray

Returns a new instance of PerfEventArray.



333
334
335
336
337
338
339
# File 'lib/rbbcc/table.rb', line 333

def initialize(bpf, map_id, map_fd, keytype, leaftype, name: nil)
  super
  @open_key_fds = {}
  @event_class = nil
  @_cbs = {}
  @_open_key_fds = {}
end

Instance Method Details

#_open_perf_buffer(cpu, callback, page_cnt, lost_cb) ⇒ Object



358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
# File 'lib/rbbcc/table.rb', line 358

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

#event(data) ⇒ Object



341
342
343
344
345
346
# File 'lib/rbbcc/table.rb', line 341

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) ⇒ Object



348
349
350
351
352
353
354
355
356
# File 'lib/rbbcc/table.rb', line 348

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