On Wed, Jun 12, 2019 at 02:11:44PM +0800, Jin, Yao wrote: > > > On 6/11/2019 4:56 PM, Jiri Olsa wrote: > > On Sat, Jun 08, 2019 at 07:41:47PM +0800, Jin, Yao wrote: > > > > > > > > > On 6/5/2019 7:44 PM, Jiri Olsa wrote: > > > > On Mon, Jun 03, 2019 at 10:36:14PM +0800, Jin Yao wrote: > > > > > > > > SNIP > > > > > > > > > diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h > > > > > index 43623fa..d1641da 100644 > > > > > --- a/tools/perf/util/sort.h > > > > > +++ b/tools/perf/util/sort.h > > > > > @@ -79,6 +79,9 @@ struct hist_entry_diff { > > > > > /* HISTC_WEIGHTED_DIFF */ > > > > > s64 wdiff; > > > > > + > > > > > + /* PERF_HPP_DIFF__CYCLES */ > > > > > + s64 cycles; > > > > > }; > > > > > }; > > > > > @@ -143,6 +146,9 @@ struct hist_entry { > > > > > struct branch_info *branch_info; > > > > > long time; > > > > > struct hists *hists; > > > > > + void *block_hists; > > > > > + int block_idx; > > > > > + int block_num; > > > > > struct mem_info *mem_info; > > > > > struct block_info *block_info; > > > > > > > > could you please not add the new block* stuff in here, > > > > and instead use the "c2c model" and use yourr own struct > > > > on top of hist_entry? we are trying to librarize this > > > > stuff and keep only necessary things in here.. > > > > > > > > you're already using hist_entry_ops, so should be easy > > > > > > > > something like: > > > > > > > > struct block_hist_entry { > > > > void *block_hists; > > > > int block_idx; > > > > int block_num; > > > > struct block_info *block_info; > > > > > > > > struct hist_entry he; > > > > }; > > > > > > > > > > > > > > > > jirka > > > > > > > > > > Hi Jiri, > > > > > > After more considerations, maybe I can't move these stuffs from hist_entry > > > to block_hist_entry. > > > > why? > > > > > > > > Actually we use 2 kinds of hist_entry in this patch series. On kind of > > > hist_entry is for symbol/function. The other kind of hist_entry is for > > > basic > > > block. > > > > correct > > > > so the way I see it the processing goes like this: > > > > > > 1) there's standard hist_entry processing ending up > > with evsel->hists->rb_root full of hist entries > > > > 2) then you process every hist_entry and create > > new 'struct hists' for each and fill it with > > symbol counts data > > > > > > > > you could add 'struct hist_entry_ops' for the 1) processing > > that adds the 'struct hists' object for each hist_entry > > > > and add another 'struct hist_entry_ops' for 2) processing > > to carry the block data for each hist_entry > > > > jirka > > > > Hi Jiri, > > Yes, I can use two hist_entry_ops but one thing is still difficult to handle > that is the printing of blocks. > > One function may contain multiple blocks so I add 'block_num' in 'struct > hist_entry' to record the number of blocks. > > In patch "perf diff: Print the basic block cycles diff", I reuse most of > current code to print the blocks. The major change is: > > static int hist_entry__fprintf(struct hist_entry *he, size_t size, > char *bf, size_t bfsz, FILE *fp, > bool ignore_callchains) { > > + if (he->block_hists) > + return hist_entry__block_fprintf(he, bf, size, fp); > +
you could do it the way we do hierarchy and have something like 'symbol_conf.report_block' if (symbol_conf.report_hierarchy) return hist_entry__hierarchy_fprintf(he, &hpp, hists, fp); and in hist_entry__block_fprintf you cast the hist_entry to your struct.. so you'll have all the data jirka > hist_entry__snprintf(he, &hpp); > } > > +static int hist_entry__block_fprintf(struct hist_entry *he, > + char *bf, size_t size, > + FILE *fp) > +{ > + int ret = 0; > + > + for (int i = 0; i < he->block_num; i++) { > + struct perf_hpp hpp = { > + .buf = bf, > + .size = size, > + .skip = false, > + }; > + > + he->block_idx = i; > + hist_entry__snprintf(he, &hpp); > + > + if (!hpp.skip) > + ret += fprintf(fp, "%s\n", bf); > + } > + > + return ret; > +} > + > > So it looks at least I need to add 'block_num' to 'struct hist_entry', > otherwise I can't reuse most of codes. > > Any idea for 'block_num'? > > Thanks > Jin Yao