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.



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

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



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
422
423
# File 'lib/rbbcc/table.rb', line 383

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



366
367
368
369
370
371
# File 'lib/rbbcc/table.rb', line 366

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



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

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