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

Returns a new instance of PerfEventArray.



369
370
371
372
373
374
375
# File 'lib/rbbcc/table.rb', line 369

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



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
424
425
426
427
428
429
430
431
432
433
434
# File 'lib/rbbcc/table.rb', line 394

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



377
378
379
380
381
382
# File 'lib/rbbcc/table.rb', line 377

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_perf_buffer(page_cnt: 8, lost_cb: nil, &callback) ⇒ Object



384
385
386
387
388
389
390
391
392
# File 'lib/rbbcc/table.rb', line 384

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