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, from_pin, #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.



356
357
358
359
360
361
362
# File 'lib/rbbcc/table.rb', line 356

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



381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
# File 'lib/rbbcc/table.rb', line 381

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



364
365
366
367
368
369
# File 'lib/rbbcc/table.rb', line 364

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



371
372
373
374
375
376
377
378
379
# File 'lib/rbbcc/table.rb', line 371

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