/** Event number => tracebuffer index. * @param nr number of event * @return tracebuffer index of event which has the number nr or * -1 if there is no event with this number or * -2 if the event is currently hidden. */ PUBLIC static Mword Jdb_tbuf::search_to_idx(Mword nr) { if (nr == (Mword) - 1) return (Mword) - 1; Tb_entry *e; if (!_filter_enabled) { e = search(nr); if (!e) return (Mword) - 1; return unfiltered_idx(e); } for (Mword idx_u = 0, idx_f = 0; (e = unfiltered_lookup(idx_u)); idx_u++) { if (e->number() == nr) return e->hidden() ? (Mword) - 2 : idx_f; if (!e->hidden()) idx_f++; } return (Mword)-1; }
/** Return pointer to new tracebuffer entry. */ PUBLIC static Tb_entry* Jdb_tbuf::new_entry() { Tb_entry *tb; { auto guard = lock_guard(_lock); tb = _tbuf_act; status()->current = (Address)tb; if (++_tbuf_act >= _tbuf_max) _tbuf_act = buffer(); if (_entries < _max_entries) _entries++; tb->number(++_number); } tb->rdtsc(); tb->rdpmc1(); tb->rdpmc2(); return tb; }
/** Event number => Tb_entry. */ PUBLIC static inline Tb_entry* Jdb_tbuf::search(Mword nr) { Tb_entry *e; for (Mword idx = 0; (e = unfiltered_lookup(idx)); idx++) if (e->number() == nr) return e; return 0; }
/** Get difference CPU cycles between event idx and event idx+1. * @param idx position of first event in tracebuffer * @retval difference in CPU cycles * @return 0 if something wrong, 1 if everything ok */ PUBLIC static int Jdb_tbuf::diff_tsc(Mword idx, Signed64 *delta) { Tb_entry *e = lookup(idx); Tb_entry *e_prev = lookup(idx+1); if (!e || !e_prev) return false; *delta = e->tsc() - e_prev->tsc(); return true; }
/** Get difference perfcnt cycles between event idx and event idx+1. * @param idx position of first event in tracebuffer * @param nr number of perfcounter (0=first, 1=second) * @retval difference in perfcnt cycles * @return 0 if something wrong, 1 if everything ok */ PUBLIC static int Jdb_tbuf::diff_pmc(Mword idx, Mword nr, Signed32 *delta) { Tb_entry *e = lookup(idx); Tb_entry *e_prev = lookup(idx + 1); if (!e || !e_prev) return false; switch (nr) { case 0: *delta = e->pmc1() - e_prev->pmc1(); break; case 1: *delta = e->pmc2() - e_prev->pmc2(); break; } return true; }
/** Return pointer to tracebuffer event. * Don't count hidden events. * @param position of event in tracebuffer: * 0 is last event, 1 the event before and so on * @return pointer to tracebuffer event * * event with idx == 0 is the last event queued in * event with idx == 1 is the event before */ PUBLIC static Tb_entry* Jdb_tbuf::lookup(Mword look_idx) { if (!_filter_enabled) return unfiltered_lookup(look_idx); for (Mword idx = 0;; idx++) { Tb_entry *e = unfiltered_lookup(idx); if (!e) return 0; if (e->hidden()) continue; if (!look_idx--) return e; } }
/** Get difference CPU cycles between event idx and event idx+1 on the same CPU. * @param idx position of first event in tracebuffer * @retval difference in CPU cycles * @return 0 if something wrong, 1 if everything ok */ PUBLIC static int Jdb_tbuf::diff_tsc(Mword idx, Signed64 *delta) { Tb_entry *e = lookup(idx); Tb_entry *e_prev; if (!e) return false; do { e_prev = lookup(++idx); if (!e_prev) return false; } while (e->cpu() != e_prev->cpu()); *delta = e->tsc() - e_prev->tsc(); return true; }
/** Return some information about log event. * @param idx number of event to determine the info * @retval number event number * @retval tsc event value of CPU cycles * @retval pmc event value of perf counter cycles * @return 0 if something wrong, 1 if everything ok */ PUBLIC static int Jdb_tbuf::event(Mword idx, Mword *number, Unsigned32 *kclock, Unsigned64 *tsc, Unsigned32 *pmc1, Unsigned32 *pmc2) { Tb_entry *e = lookup(idx); if (!e) return false; *number = e->number(); if (kclock) *kclock = e->kclock(); if (tsc) *tsc = e->tsc(); if (pmc1) *pmc1 = e->pmc1(); if (pmc2) *pmc2 = e->pmc2(); return true; }