Update of /cvsroot/oprofile/oprofile/pp In directory sc8-pr-cvs1:/tmp/cvs-serv22966/pp Modified Files: Makefile.am format_output.cpp format_output.h op_merge.cpp op_time.cpp op_to_source.cpp oprofpp.cpp symbol_container_imp.cpp symbol_container_imp.h Added Files: counter_profile.cpp counter_profile.h profile.cpp profile.h profile_container.cpp profile_container.h Removed Files: opp_samples_files.cpp opp_samples_files.h samples_container.cpp samples_container.h samples_file.cpp samples_file.h Log Message: class renaming, corresponding filename renaming. No code really change. regards, Phil --- NEW FILE: counter_profile.cpp --- /** * @file counter_profile.cpp * Encapsulation of one samples files * * @remark Copyright 2002 OProfile authors * @remark Read the file COPYING * * @author Philippe Elie * @author John Levon */ #include "op_file.h" #include "op_config.h" #include "op_events.h" #include "op_events_desc.h" #include "op_print_event.h" #include "op_sample_file.h" #include "string_manip.h" #include "counter_array.h" #include "counter_profile.h" #include <cerrno> #include <unistd.h> #include <iostream> using namespace std; counter_profile_t::counter_profile_t(string const & filename) : start_offset(0) { db_open(&samples_db, filename.c_str(), DB_RDONLY, sizeof(struct opd_header)); opd_header const & head = header(); if (head.version != OPD_VERSION) { cerr << "oprofpp: samples files version mismatch, are you " "running a daemon and post-profile tools with version " "mismatch ?" << endl; exit(EXIT_FAILURE); } build_ordered_samples(); } counter_profile_t::~counter_profile_t() { db_close(&samples_db); } void counter_profile_t::check_headers(counter_profile_t const & rhs) const { opd_header const & f1 = header(); opd_header const & f2 = rhs.header(); if (f1.mtime != f2.mtime) { cerr << "oprofpp: header timestamps are different (" << f1.mtime << ", " << f2.mtime << ")\n"; exit(EXIT_FAILURE); } if (f1.is_kernel != f2.is_kernel) { cerr << "oprofpp: header is_kernel flags are different\n"; exit(EXIT_FAILURE); } if (f1.cpu_speed != f2.cpu_speed) { cerr << "oprofpp: header cpu speeds are different (" << f1.cpu_speed << ", " << f2.cpu_speed << ")\n"; exit(EXIT_FAILURE); } if (f1.separate_samples != f2.separate_samples) { cerr << "oprofpp: header separate_samples are different (" << f1.separate_samples << ", " << f2.separate_samples << ")\n"; exit(EXIT_FAILURE); } } void counter_profile_t::build_ordered_samples() { db_node_nr_t node_nr, pos; db_node_t * node = db_get_iterator(&samples_db, &node_nr); for ( pos = 0 ; pos < node_nr ; ++pos) { if (node[pos].key) { ordered_samples_t::value_type val(node[pos].key, node[pos].value); ordered_samples.insert(val); } } } u32 counter_profile_t::count(uint start, uint end) const { u32 count = 0; ordered_samples_t::const_iterator first, last; first = ordered_samples.lower_bound(start - start_offset); last = ordered_samples.lower_bound(end - start_offset); for ( ; first != last ; ++first) { count += first->second; } return count; } --- NEW FILE: counter_profile.h --- /** * @file counter_profile.h * Encapsulation of one samples file * * @remark Copyright 2002 OProfile authors * @remark Read the file COPYING * * @author Philippe Elie * @author John Levon */ #ifndef COUNTER_PROFILE_H #define COUNTER_PROFILE_H #include <string> #include <map> #include "db_hash.h" #include "op_types.h" #include "op_hw_config.h" #include "utility.h" class counter_array_t; class opd_header; /** A class to store a sample file for one counter */ class counter_profile_t /*:*/ noncopyable { public: /** * counter_profile_t - construct a counter_profile_t object * @param filename the full path of sample file * * open and mmap the samples file specified by filename * samples file header coherence are checked * * all error are fatal */ counter_profile_t(std::string const & filename); /** * ~counter_profile_t - destroy a counter_profile_t object * * close and unmap the samples file */ ~counter_profile_t(); /** * check_headers - check that the lhs and rhs headers are * coherent (same size, same mtime etc.) * @param headers the other counter_profile_t * * all errors are fatal */ void check_headers(counter_profile_t const & headers) const; /// return the sample count at the given position u32 count(uint start) const { return count(start, start + 1); } /** * count - return the number of samples in given range * @param start start samples nr of range * @param end end samples nr of range * * return the number of samples in the the range [start, end) * no range checking is performed. */ u32 count(uint start, uint end) const; /// return the header of this sample file opd_header const & header() const { return *static_cast<opd_header *>(samples_db.base_memory); } /// see member variable start_offset void set_start_offset(u32 start_offset_) { start_offset = start_offset_; } private: /// storage type for samples sorted by eip typedef std::map<db_key_t, db_value_t> ordered_samples_t; /// helper to build ordered samples by eip void build_ordered_samples(); /// the underlying db object samples_db_t samples_db; /** * Samples are stored in hash table, iterating over hash table don't * provide any ordering, the above count() interface rely on samples * ordered by eip. This map is only a temporary storage where samples * are ordered by eip. */ ordered_samples_t ordered_samples; /** * For the kernel and kernel modules, this value is non-zero and * equal to the offset of the .text section. This is done because * we use the information provided in /proc/ksyms, which only gives * the mapped position of .text, and the symbol _text from * vmlinux. This value is used to fix up the sample offsets * for kernel code as a result of this difference (in user-space * samples, the sample offset is from the start of the mapped * file, as seen in /proc/pid/maps). */ u32 start_offset; }; #endif /* !COUNTER_PROFILE_H */ --- NEW FILE: profile.cpp --- /** * @file profile.cpp * Encapsulation for samples files over all counter belonging to the * same binary image * * @remark Copyright 2002 OProfile authors * @remark Read the file COPYING * * @author Philippe Elie * @author John Levon */ #include <unistd.h> #include <iostream> #include <string> #include <cerrno> #include "op_file.h" #include "op_cpu_type.h" #include "counter_array.h" #include "op_sample_file.h" #include "string_manip.h" #include "op_print_event.h" #include "profile.h" using namespace std; profile_t::profile_t(string const & sample_file, int counter_) : nr_counters(2), sample_filename(sample_file), counter_mask(counter_), first_file(-1) { uint i, j; time_t mtime = 0; /* no samplefiles open initially */ for (i = 0; i < OP_MAX_COUNTERS; ++i) { samples[i] = 0; } for (i = 0; i < OP_MAX_COUNTERS ; ++i) { if ((counter_mask & (1 << i)) != 0) { /* if only the i th bit is set in counter spec we do * not allow opening failure to get a more precise * error message */ open_samples_file(i, (counter_mask & ~(1 << i)) != 0); } } /* find first open file */ for (first_file = 0; first_file < OP_MAX_COUNTERS ; ++first_file) { if (samples[first_file] != 0) break; } if (first_file == OP_MAX_COUNTERS) { cerr << "Can not open any samples files for " << sample_filename << ". Last error " << strerror(errno) << endl; exit(EXIT_FAILURE); } opd_header const & header = samples[first_file]->header(); mtime = header.mtime; /* determine how many counters are possible via the sample file */ op_cpu cpu = static_cast<op_cpu>(header.cpu_type); nr_counters = op_get_nr_counters(cpu); /* check sample files match */ for (j = first_file + 1; j < OP_MAX_COUNTERS; ++j) { if (samples[j] == 0) continue; samples[first_file]->check_headers(*samples[j]); } } profile_t::~profile_t() { uint i; for (i = 0 ; i < OP_MAX_COUNTERS; ++i) { delete samples[i]; } } void profile_t::check_mtime(string const & file) const { time_t const newmtime = op_get_mtime(file.c_str()); if (newmtime != first_header().mtime) { cerr << "oprofpp: WARNING: the last modified time of the binary file " << file << " does not match\n" << "that of the sample file. Either this is the wrong binary or the binary\n" << "has been modified since the sample file was created.\n"; } } void profile_t::open_samples_file(u32 counter, bool can_fail) { string filename = ::sample_filename(string(), sample_filename, counter); if (access(filename.c_str(), R_OK) == 0) { samples[counter] = new counter_profile_t(filename); } else { if (!can_fail) { cerr << "oprofpp: Opening " << filename << "failed." << strerror(errno) << endl; exit(EXIT_FAILURE); } } } bool profile_t::accumulate_samples(counter_array_t & counter, uint index) const { bool found_samples = false; for (uint k = 0; k < nr_counters; ++k) { u32 count = samples_count(k, index); if (count) { counter[k] += count; found_samples = true; } } return found_samples; } bool profile_t::accumulate_samples(counter_array_t & counter, uint start, uint end) const { bool found_samples = false; for (uint k = 0; k < nr_counters; ++k) { if (is_open(k)) { counter[k] += samples[k]->count(start, end); if (counter[k]) found_samples = true; } } return found_samples; } void profile_t::set_start_offset(u32 start_offset) { if (!first_header().is_kernel) return; for (uint k = 0; k < nr_counters; ++k) { if (is_open(k)) samples[k]->set_start_offset(start_offset); } } /** * output_header() - output counter setup * * output to stdout the cpu type, cpu speed * and all counter description available */ void profile_t::output_header() const { opd_header const & header = first_header(); op_cpu cpu = static_cast<op_cpu>(header.cpu_type); cout << "Cpu type: " << op_get_cpu_type_str(cpu) << endl; cout << "Cpu speed was (MHz estimation) : " << header.cpu_speed << endl; for (uint i = 0 ; i < OP_MAX_COUNTERS; ++i) { if (samples[i] != 0) { op_print_event(cout, i, cpu, header.ctr_event, header.ctr_um, header.ctr_count); } } } --- NEW FILE: profile.h --- /** * @file opp_samples_files.h * Encapsulation for samples files over all counter belonging to the * same binary image * * @remark Copyright 2002 OProfile authors * @remark Read the file COPYING * * @author Philippe Elie * @author John Levon */ #ifndef OPP_SAMPLES_FILES_H #define OPP_SAMPLES_FILES_H #include <string> #include "op_types.h" #include "op_hw_config.h" #include "utility.h" #include "counter_profile.h" /** A class to store sample files over all counters */ class profile_t /*:*/ noncopyable { public: /** * profile_t - construct an profile_t object * @param sample_file the base name of sample file * @param counter which samples files to open, -1 means try to open * all samples files. * * at least one sample file (based on sample_file name) * must be opened. If more than one sample file is open * their header must be coherent. Each header is also * sanitized. * * all error are fatal */ profile_t(std::string const & sample_file, int counter); ~profile_t(); /** * check_mtime - check mtime of samples file against file */ void check_mtime(std::string const & file) const; /** * is_open - test if a samples file is open * @param i index of the samples file to check. * * return true if the samples file index is open */ bool is_open(int i) const { return samples[i] != 0; } /** * @param i index of the samples files * @param sample_nr number of the samples to test. * * return the number of samples for samples file index at position * sample_nr. return 0 if the samples file is close or there is no * samples at position sample_nr */ uint samples_count(int i, int sample_nr) const { return is_open(i) ? samples[i]->count(sample_nr) : 0; } /** * accumulate_samples - lookup samples from a vma address * @param counter where to accumulate the samples * @param vma index of the samples. * * return false if no samples has been found */ bool accumulate_samples(counter_array_t & counter, uint vma) const; /** * accumulate_samples - lookup samples from a range of vma address * @param counter where to accumulate the samples * @param start start index of the samples. * @param end end index of the samples. * * return false if no samples has been found */ bool accumulate_samples(counter_array_t & counter, uint start, uint end) const; /** * output_header() - output counter setup * * output to stdout the cpu type, cpu speed * and all counter description available */ void output_header() const; /// return the header of the first opened samples file opd_header const & first_header() const { return samples[first_file]->header(); } /** * Set the start offset of the underlying samples files * to non-zero (derived from the BFD) iff this contains * the kernel or kernel module sample files. */ void set_start_offset(u32 start_offset); // TODO privatize when we can counter_profile_t * samples[OP_MAX_COUNTERS]; uint nr_counters; private: std::string sample_filename; // used in do_list_xxxx/do_dump_gprof. size_t counter_mask; // cached value: index to the first opened file, setup as nearly as we // can in ctor. int first_file; /** * open_samples_file - ctor helper * @param counter the counter number * @param can_fail allow to fail gracefully * * open and mmap the given samples files, * the member var samples[counter], header[counter] * etc. are updated in case of success. * The header is checked but coherence between * header can not be sanitized at this point. * * if !can_fail all errors are fatal. */ void open_samples_file(u32 counter, bool can_fail); }; #endif /* !OPP_SAMPLES_FILES_H */ --- NEW FILE: profile_container.cpp --- /** * @file profile_container.cpp * profile file container * * @remark Copyright 2002 OProfile authors * @remark Read the file COPYING * * @author Philippe Elie * @author John Levon */ #include <set> #include <vector> #include <string> #include <iostream> #include <algorithm> #include "symbol_functors.h" #include "profile_container.h" #include "profile.h" #include "sample_container_imp.h" #include "symbol_container_imp.h" using namespace std; namespace { struct filename_by_samples { filename_by_samples(string filename_, double percent_) : filename(filename_), percent(percent_) {} bool operator<(filename_by_samples const & lhs) const { if (percent != lhs.percent) return percent > lhs.percent; return filename > lhs.filename; } string filename; // ratio of samples which belongs to this filename. double percent; }; } profile_container_t::profile_container_t(bool add_zero_samples_symbols_, outsymbflag flags_, int counter_mask_) : symbols(new symbol_container_imp_t), samples(new sample_container_imp_t), nr_counters(static_cast<uint>(-1)), add_zero_samples_symbols(add_zero_samples_symbols_), flags(flags_), counter_mask(counter_mask_) { } profile_container_t::~profile_container_t() { } // Post condition: // the symbols/samples are sorted by increasing vma. // the range of sample_entry inside each symbol entry are valid // the samples_by_file_loc member var is correctly setup. void profile_container_t:: add(profile_t const & profile, op_bfd const & abfd, string const & symbol_name) { // paranoid checking if (nr_counters != static_cast<uint>(-1) && nr_counters != profile.nr_counters) { cerr << "Fatal: profile_container_t::do_add(): mismatch" << "between nr_counters and profile.nr_counters\n"; exit(EXIT_FAILURE); } nr_counters = profile.nr_counters; string const image_name = abfd.get_filename(); bool const need_linenr = (flags & (osf_linenr_info | osf_short_linenr_info)); bool const need_details = (flags & osf_details); for (symbol_index_t i = 0 ; i < abfd.syms.size(); ++i) { if (!symbol_name.empty() && abfd.syms[i].name() != symbol_name) continue; u32 start, end; string filename; uint linenr; symbol_entry symb_entry; abfd.get_symbol_range(i, start, end); bool const found_samples = profile.accumulate_samples(symb_entry.sample.counter, start, end); if (found_samples == 0 && !add_zero_samples_symbols) continue; symb_entry.size = end - start; counter += symb_entry.sample.counter; symb_entry.name = abfd.syms[i].name(); if (need_linenr && abfd.get_linenr(i, start, filename, linenr)) { symb_entry.sample.file_loc.filename = filename; symb_entry.sample.file_loc.linenr = linenr; } else { symb_entry.sample.file_loc.linenr = 0; } symb_entry.sample.file_loc.image_name = image_name; bfd_vma base_vma = abfd.syms[i].vma(); symb_entry.sample.vma = abfd.sym_offset(i, start) + base_vma; symb_entry.first = samples->size(); if (need_details) { add_samples(profile, abfd, i, start, end, base_vma, image_name); } symb_entry.last = samples->size(); symbols->push_back(symb_entry); } } void profile_container_t::add_samples(profile_t const & profile, op_bfd const & abfd, symbol_index_t sym_index, u32 start, u32 end, bfd_vma base_vma, string const & image_name) { bool const need_linenr = (flags & (osf_linenr_info | osf_short_linenr_info)); for (u32 pos = start; pos < end ; ++pos) { string filename; sample_entry sample; uint linenr; if (!profile.accumulate_samples(sample.counter, pos)) continue; if (need_linenr && sym_index != size_t(-1) && abfd.get_linenr(sym_index, pos, filename, linenr)) { sample.file_loc.filename = filename; sample.file_loc.linenr = linenr; } else { sample.file_loc.linenr = 0; } sample.file_loc.image_name = image_name; sample.vma = (sym_index != nil_symbol_index) ? abfd.sym_offset(sym_index, pos) + base_vma : pos; samples->push_back(sample); } } profile_container_t::symbol_collection const profile_container_t::select_symbols(size_t ctr, double threshold, bool until_threshold, bool sort_by_vma) const { symbol_collection v; symbol_collection result; symbols->get_symbols_by_count(ctr, v); u32 const total_count = samples_count(ctr); symbol_collection::const_iterator it = v.begin(); symbol_collection::const_iterator const end = v.end(); for (; it < end && threshold >= 0; ++it) { double const percent = op_ratio((*it)->sample.counter[ctr], total_count); if (until_threshold || percent >= threshold) result.push_back((*it)); if (until_threshold) threshold -= percent; } if (sort_by_vma) { sort(result.begin(), result.end(), less_sample_entry_by_vma()); } return result; } vector<string> const profile_container_t::select_filename( size_t ctr, double threshold, bool until_threshold) const { vector<string> result; set<string> filename_set; // Trying to iterate on symbols to create the set of filenames which // contain sample does not work: a symbol can contain samples and this // symbol is in a source file that contain zero sample because only // inline function in this source file contains samples. for (size_t i = 0 ; i < samples->size() ; ++i) { filename_set.insert((*samples)[i].file_loc.filename); } // Give a sort order on filename for the selected counter. vector<filename_by_samples> file_by_samples; u32 total_count = samples_count(ctr); set<string>::const_iterator it = filename_set.begin(); set<string>::const_iterator const end = filename_set.end(); for (; it != end; ++it) { counter_array_t counter; samples_count(counter, *it); filename_by_samples f(*it, op_ratio(counter[ctr], total_count)); file_by_samples.push_back(f); } // now sort the file_by_samples entry. sort(file_by_samples.begin(), file_by_samples.end()); vector<filename_by_samples>::const_iterator cit = file_by_samples.begin(); vector<filename_by_samples>::const_iterator const cend = file_by_samples.end(); for (; cit != cend && threshold >= 0; ++cit) { filename_by_samples const & s = *cit; if (until_threshold || s.percent >= threshold) result.push_back(s.filename); if (until_threshold) threshold -= s.percent; } return result; } // Rest here are delegated to our private implementation. symbol_entry const * profile_container_t::find_symbol(bfd_vma vma) const { return symbols->find_by_vma(vma); } symbol_entry const * profile_container_t::find_symbol(string const & filename, size_t linenr) const { return symbols->find(filename, linenr); } symbol_entry const * profile_container_t::find_symbol(string const & name) const { return symbols->find(name); } sample_entry const * profile_container_t::find_sample(bfd_vma vma) const { return samples->find_by_vma(vma); } u32 profile_container_t::samples_count(size_t counter_nr) const { return counter[counter_nr]; } bool profile_container_t::samples_count(counter_array_t & result, string const & filename) const { return samples->accumulate_samples(result, filename, get_nr_counters()); } bool profile_container_t::samples_count(counter_array_t & result, string const & filename, size_t linenr) const { return samples->accumulate_samples(result, filename, linenr, get_nr_counters()); } sample_entry const & profile_container_t::get_samples(sample_index_t idx) const { return (*samples)[idx]; } uint profile_container_t::get_nr_counters() const { if (nr_counters != static_cast<uint>(-1)) return nr_counters; cerr << "Fatal: profile_container_t::get_nr_counters() attempt to\n" << "access a samples container w/o any samples files. Please\n" << "report this bug to <opr...@li...>\n"; exit(EXIT_FAILURE); } bool add_samples(profile_container_t & samples, string sample_filename, size_t counter_mask, string image_name, vector<string> const & excluded_symbols, string symbol) { profile_t profile(sample_filename, counter_mask); op_bfd abfd(image_name, excluded_symbols, vector<string>()); profile.check_mtime(image_name); profile.set_start_offset(abfd.get_start_offset()); samples.add(profile, abfd, symbol); return abfd.have_debug_info(); } --- NEW FILE: profile_container.h --- /** * @file profile_container.h * Container associating symbols and samples * * @remark Copyright 2002 OProfile authors * @remark Read the file COPYING * * @author Philippe Elie * @author John Levon */ #ifndef PROFILE_CONTAINER_H #define PROFILE_CONTAINER_H #include <string> #include <vector> #include "opp_symbol.h" #include "outsymbflag.h" #include "utility.h" #include "op_bfd.h" class sample_container_imp_t; class symbol_container_imp_t; class profile_t; /** store multiple samples files belonging to the same profling session. * So on can hold samples files for arbitrary counter and binary image */ class profile_container_t /*:*/ noncopyable { public: /** * Build an object to store information on samples. All parameters * acts as hint for what you will request after recording samples and * so on allow optimizations during recording the information. * @param add_zero_samples_symbols must we add to the symbol container * symbols with zero samples count * @param flags optimize hint to add samples. The flags is a promise * on what will be required as information in future. Avoid to pass * osf_linenr_info greatly improve performance of add. Avoiding * osf_details is also an improvement. * @param counter_mask which counter we must record */ profile_container_t(bool add_zero_samples_symbols, outsymbflag flags, int counter_mask); ~profile_container_t(); /** * add() - record symbols/samples in the underlined container * @param profile the samples files container * @param abfd the associated bfd object * @param symbol_name if non empty add will record samples only * for this symbol name else all samples will be recorded * * add() is an helper for delayed ctor. Take care you can't safely * make any call to add after any other member function call. * Obviously you can add only samples files which are coherent (same * sampling rate, same events etc.) */ void add(profile_t const & profile, op_bfd const & abfd, std::string const & symbol_name = std::string()); /// Find a symbol from its vma, return zero if no symbol at this vma symbol_entry const * find_symbol(bfd_vma vma) const; /// Find a symbol from its name, return zero if no symbol found symbol_entry const * find_symbol(std::string const & name) const; /// Find a symbol from its filename, linenr, return zero if no symbol /// at this location symbol_entry const * find_symbol(std::string const & filename, size_t linenr) const; /// Find a sample by its vma, return zero if no sample at this vma sample_entry const * find_sample(bfd_vma vma) const; /// Return a sample_entry by its index, index must be valid sample_entry const & get_samples(sample_index_t idx) const; /// a collection of sorted symbols typedef std::vector<symbol_entry const *> symbol_collection; /** * select_symbols - create a set of symbols sorted by sample count * @param ctr on what counter sorting must be made and threshold * selection must be made * @param threshold select symbols which contains more than * threshold percent of samples * @param until_threshold rather to get symbols with more than * percent threshold samples select symbols until the cumulated * count of samples reach threshold percent * @param sort_by_vma sort symbols by vma not counter samples * @return a sorted vector of symbols * * until_threshold and threshold acts like the -w and -u options * of op_to_source. If you need to get all symbols call it with * threshold == 0.0 and !until_threshold */ symbol_collection const select_symbols( size_t ctr, double threshold, bool until_threshold, bool sort_by_vma = false) const; /// Like select_symbols for filename without allowing sort by vma. std::vector<std::string> const select_filename(size_t ctr, double threshold, bool until_threshold) const; /// return the total number of samples for counter_nr u32 samples_count(size_t counter_nr) const; /// Get the samples count which belongs to filename. Return false if /// no samples found. bool samples_count(counter_array_t & result, std::string const & filename) const; /// Get the samples count which belongs to filename, linenr. Return /// false if no samples found. bool samples_count(counter_array_t & result, std::string const & filename, size_t linenr) const; /// you can call this *after* the first call to add() else the /// application exit(1) with a meaningfull error message uint get_nr_counters() const; private: /// helper for do_add() void add_samples(profile_t const & profile, op_bfd const & abfd, symbol_index_t sym_index, u32 start, u32 end, bfd_vma base_vma, std::string const & image_name); /** * create an unique artificial symbol for an offset range. The range * is only a hint of the maximum size of the created symbol. We * give to the symbol an unique name as ?image_file_name#order and * a range up to the nearest of syms or for the whole range if no * syms exist after the start offset. the end parameter is updated * to reflect the symbol range. * * The rationale here is to try to create symbols for alignment between * function as little as possible and to create meaningfull symbols * for special case such image w/o symbol. */ std::string create_artificial_symbol(op_bfd const & abfd, u32 start, u32 & end, size_t & order); /// The symbols collected by oprofpp sorted by increased vma, provide /// also a sort order on samples count for each counter. scoped_ptr<symbol_container_imp_t> symbols; /// The samples count collected by oprofpp sorted by increased vma, /// provide also a sort order on (filename, linenr) scoped_ptr<sample_container_imp_t> samples; /// build() must count samples count for each counter so cache it here /// since user of profile_container_t often need it later. counter_array_t counter; /// maximum number of counter available uint nr_counters; /// parameters passed to ctor bool add_zero_samples_symbols; outsymbflag flags; int counter_mask; }; /** * add_samples - populate a samples container with samples * @param samples the samples container to populate * @param sample_filename samples filename * @param counter_mask the counter nr mask each bit at pos i on mean open * this samples files nr i * @param binary_name the name of the binary image * @param excluded_symbols a vector of symbol name to ignore * @param symbol if non empty record only samples for this symbol * * open a bfd object getting symbols name, then populate samples with the * relevant samples */ bool add_samples(profile_container_t & samples, std::string sample_filename, size_t counter_mask, std::string binary_name, std::vector<std::string> const & excluded_symbols = std::vector<std::string>(), std::string symbol = std::string()); #endif /* !PROFILE_CONTAINER_H */ Index: Makefile.am =================================================================== RCS file: /cvsroot/oprofile/oprofile/pp/Makefile.am,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- Makefile.am 4 Dec 2002 20:01:46 -0000 1.4 +++ Makefile.am 8 Dec 2002 05:12:28 -0000 1.5 @@ -2,11 +2,11 @@ -I ${top_srcdir}/libopt++ -I ${top_srcdir}/libutil++ -I ${top_srcdir}/libop++ noinst_LIBRARIES = libpp.a -libpp_a_SOURCES = format_output.cpp samples_container.cpp \ +libpp_a_SOURCES = format_output.cpp profile_container.cpp \ sample_container_imp.cpp counter_array.cpp symbol_container_imp.cpp \ - derive_files.cpp counter_util.cpp samples_file.cpp \ - opp_samples_files.cpp session.cpp counter_array.h opp_samples_files.h \ - samples_container.h counter_util.h opp_symbol.h format_output.h samples_file.h \ + derive_files.cpp counter_util.cpp counter_profile.cpp \ + profile.cpp session.cpp counter_array.h profile.h profile_container.h \ + counter_util.h opp_symbol.h format_output.h counter_profile.h \ derive_files.h oprofpp_options.h session.h op_time_options.h \ outsymbflag.h symbol_container_imp.h op_to_source_options.h \ sample_container_imp.h symbol_functors.h Index: format_output.cpp =================================================================== RCS file: /cvsroot/oprofile/oprofile/pp/format_output.cpp,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- format_output.cpp 4 Dec 2002 22:54:24 -0000 1.3 +++ format_output.cpp 8 Dec 2002 05:12:28 -0000 1.4 @@ -16,7 +16,7 @@ #include "opp_symbol.h" #include "format_output.h" -#include "samples_container.h" +#include "profile_container.h" #include "demangle_symbol.h" using namespace std; @@ -90,13 +90,13 @@ } -formatter::formatter(samples_container_t const & samples_container_, int counter_) - : flags(osf_none), samples_container(samples_container_), +formatter::formatter(profile_container_t const & profile_container_, int counter_) + : flags(osf_none), profile_container(profile_container_), counter(counter_), first_output(true) { - for (size_t i = 0 ; i < samples_container.get_nr_counters() ; ++i) { - total_count[i] = samples_container.samples_count(i); - total_count_details[i] = samples_container.samples_count(i); + for (size_t i = 0 ; i < profile_container.get_nr_counters() ; ++i) { + total_count[i] = profile_container.samples_count(i); + total_count_details[i] = profile_container.samples_count(i); cumulated_samples[i] = 0; cumulated_percent[i] = 0; cumulated_percent_details[i] = 0; @@ -185,7 +185,7 @@ u32 temp_cumulated_samples[OP_MAX_COUNTERS]; u32 temp_cumulated_percent[OP_MAX_COUNTERS]; - for (size_t i = 0 ; i < samples_container.get_nr_counters() ; ++i) { + for (size_t i = 0 ; i < profile_container.get_nr_counters() ; ++i) { temp_total_count[i] = total_count[i]; temp_cumulated_samples[i] = cumulated_samples[i]; temp_cumulated_percent[i] = cumulated_percent[i]; @@ -199,11 +199,11 @@ for (sample_index_t cur = symb->first ; cur != symb->last ; ++cur) { out << ' '; - do_output(out, symb->name, samples_container.get_samples(cur), + do_output(out, symb->name, profile_container.get_samples(cur), static_cast<outsymbflag>(flags & osf_details_mask)); } - for (size_t i = 0 ; i < samples_container.get_nr_counters() ; ++i) { + for (size_t i = 0 ; i < profile_container.get_nr_counters() ; ++i) { total_count[i] = temp_total_count[i]; cumulated_samples[i] = temp_cumulated_samples[i]; cumulated_percent[i] = temp_cumulated_percent[i]; @@ -224,7 +224,7 @@ } // now the repeated field. - for (size_t ctr = 0 ; ctr < samples_container.get_nr_counters(); ++ctr) { + for (size_t ctr = 0 ; ctr < profile_container.get_nr_counters(); ++ctr) { if ((counter & (1 << ctr)) != 0) { size_t repeated_flag = (flag & osf_repeat_mask); for (size_t i = 1 ; repeated_flag != 0 ; i <<= 1) { @@ -277,7 +277,7 @@ } // now the repeated field. - for (size_t ctr = 0 ; ctr < samples_container.get_nr_counters(); ++ctr) { + for (size_t ctr = 0 ; ctr < profile_container.get_nr_counters(); ++ctr) { if ((counter & (1 << ctr)) != 0) { size_t repeated_flag = (flags & osf_repeat_mask); for (size_t i = 1 ; repeated_flag != 0 ; i <<= 1) { Index: format_output.h =================================================================== RCS file: /cvsroot/oprofile/oprofile/pp/format_output.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- format_output.h 4 Dec 2002 22:54:29 -0000 1.3 +++ format_output.h 8 Dec 2002 05:12:28 -0000 1.4 @@ -22,7 +22,7 @@ #include "counter_array.h" #include "outsymbflag.h" -class samples_container_t; +class profile_container_t; class field_description; class symbol_entry; @@ -38,9 +38,9 @@ /// class to output in a columned format symbols and associated samples class formatter { public: - /// build an output_symbol object, the samples_container_t life time + /// build an output_symbol object, the profile_container_t life time /// object must be > of the life time of the output_symbol object. - formatter(samples_container_t const & samples_container, int counter); + formatter(profile_container_t const & profile_container, int counter); /// convenience to set output options flags w/o worrying about cast void set_format(outsymbflag flag); @@ -126,7 +126,7 @@ outsymbflag flags; /// container we work from - samples_container_t const & samples_container; + profile_container_t const & profile_container; /// total sample count u32 total_count[OP_MAX_COUNTERS]; Index: op_merge.cpp =================================================================== RCS file: /cvsroot/oprofile/oprofile/pp/op_merge.cpp,v retrieving revision 1.33 retrieving revision 1.34 diff -u -d -r1.33 -r1.34 --- op_merge.cpp 3 Dec 2002 01:57:58 -0000 1.33 +++ op_merge.cpp 8 Dec 2002 05:12:28 -0000 1.34 @@ -28,7 +28,7 @@ #include "op_config.h" #include "op_mangling.h" #include "op_sample_file.h" -#include "samples_file.h" +#include "counter_profile.h" using namespace std; @@ -136,11 +136,11 @@ if (filenames.empty()) return; - samples_file_t first(*filenames.begin()); + counter_profile_t first(*filenames.begin()); list<string>::const_iterator it; for (it = filenames.begin(); ++it != filenames.end(); ) { - samples_file_t next(*it); + counter_profile_t next(*it); first.check_headers(next); } Index: op_time.cpp =================================================================== RCS file: /cvsroot/oprofile/oprofile/pp/op_time.cpp,v retrieving revision 1.72 retrieving revision 1.73 diff -u -d -r1.72 -r1.73 --- op_time.cpp 4 Dec 2002 22:12:25 -0000 1.72 +++ op_time.cpp 8 Dec 2002 05:12:28 -0000 1.73 @@ -27,8 +27,8 @@ #include "op_mangling.h" #include "op_time_options.h" -#include "samples_container.h" -#include "samples_file.h" +#include "profile_container.h" +#include "profile.h" #include "format_output.h" #include "file_manip.h" @@ -37,7 +37,7 @@ using namespace std; /* TODO: if we have a quick read samples files format we can handle a great - * part of complexity here by using samples_container_t to handle straight + * part of complexity here by using profile_container_t to handle straight * op_time. Just create an artificial symbol that cover the whole samples * files with the name of the application this allow to remove image_name * and sorted_map_t class and all related stuff and to use output_symbol to @@ -282,7 +282,7 @@ if (!op_file_readable(filename)) continue; - samples_file_t samples(filename); + counter_profile_t samples(filename); u32 count = samples.count(0, ~0); @@ -450,7 +450,7 @@ */ static void output_symbols_count(map_t& files, int counter) { - samples_container_t samples(false, options::output_format_flags, counter); + profile_container_t samples(false, options::output_format_flags, counter); map_t::iterator it_f; for (it_f = files.begin() ; it_f != files.end() ; ++it_f) { Index: op_to_source.cpp =================================================================== RCS file: /cvsroot/oprofile/oprofile/pp/op_to_source.cpp,v retrieving revision 1.43 retrieving revision 1.44 diff -u -d -r1.43 -r1.44 --- op_to_source.cpp 6 Nov 2002 20:10:19 -0000 1.43 +++ op_to_source.cpp 8 Dec 2002 05:12:28 -0000 1.44 @@ -19,8 +19,8 @@ #include <stdio.h> -#include "samples_container.h" -#include "opp_samples_files.h" +#include "profile_container.h" +#include "profile.h" #include "demangle_symbol.h" #include "derive_files.h" #include "counter_util.h" @@ -84,7 +84,7 @@ /// the cpu type, we fill this var from the header of samples files op_cpu cpu_type = CPU_NO_GOOD; /// hold all info for samples -scoped_ptr<samples_container_t> samples(0); +scoped_ptr<profile_container_t> samples(0); /** * @param str the input string @@ -207,7 +207,7 @@ void do_output_one_file(ostream & out, istream & in, string const & filename); /** - * @param samples_files storage container for openeded samples files + * @param profile storage container for openeded samples files * * store opd_header information from the samples to the global * var counter_info. Caculate the total amount of samples for these samples @@ -216,7 +216,7 @@ * return false if no samples are openeded or if no cumulated count of * samples is zero */ -bool setup_counter_param(opp_samples_files const & samples_files); +bool setup_counter_param(profile_t const & profile); /** * @param out output stream @@ -374,17 +374,17 @@ if (!assembly) flag = static_cast<outsymbflag>(flag | osf_linenr_info); - samples.reset(new samples_container_t(false, flag, -1)); + samples.reset(new profile_container_t(false, flag, -1)); // this lexical scope just optimize the memory use by relaxing - // the op_bfd and opp_samples_files as short as we can. + // the op_bfd and profile_t as short as we can. { - opp_samples_files samples_files(sample_file, -1); - samples_files.check_mtime(image_name); + profile_t profile(sample_file, -1); + profile.check_mtime(image_name); op_bfd abfd(image_name, exclude_symbols, include_symbols); - samples_files.set_start_offset(abfd.get_start_offset()); + profile.set_start_offset(abfd.get_start_offset()); if (!assembly && !abfd.have_debug_info()) { cerr << "Request for source file annotated " @@ -393,13 +393,13 @@ return false; } - cpu_speed = samples_files.first_header().cpu_speed; - uint tmp = samples_files.first_header().cpu_type; + cpu_speed = profile.first_header().cpu_speed; + uint tmp = profile.first_header().cpu_type; cpu_type = static_cast<op_cpu>(tmp); - samples->add(samples_files, abfd); + samples->add(profile, abfd); - if (!setup_counter_param(samples_files)) + if (!setup_counter_param(profile)) return false; } @@ -725,24 +725,24 @@ // so on user can known total nr of samples for this source // later we must add code that iterate through symbol in this // file to output one annotation for each symbol. To do this we - // need a select_symbol(filename); in samples_container_t which + // need a select_symbol(filename); in profile_container_t which // fall back to the implementation in symbol_container_imp_t // using a lazilly build symbol_map sorted by filename // (necessary functors already exist in symbol_functors.h) } } -bool setup_counter_param(opp_samples_files const & samples_files) +bool setup_counter_param(profile_t const & profile) { bool have_counter_info = false; - for (size_t i = 0 ; i < samples_files.nr_counters ; ++i) { - if (!samples_files.is_open(i)) + for (size_t i = 0 ; i < profile.nr_counters ; ++i) { + if (!profile.is_open(i)) continue; counter_info[i].enabled = true; - opd_header const & header = samples_files.samples[i]->header(); + opd_header const & header = profile.samples[i]->header(); counter_info[i].ctr_event = header.ctr_event; counter_info[i].unit_mask = header.ctr_um; counter_info[i].event_count_sample = header.ctr_count; Index: oprofpp.cpp =================================================================== RCS file: /cvsroot/oprofile/oprofile/pp/oprofpp.cpp,v retrieving revision 1.88 retrieving revision 1.89 diff -u -d -r1.88 -r1.89 --- oprofpp.cpp 4 Dec 2002 22:12:33 -0000 1.88 +++ oprofpp.cpp 8 Dec 2002 05:12:28 -0000 1.89 @@ -22,8 +22,8 @@ #include "string_manip.h" #include "op_mangling.h" -#include "samples_container.h" -#include "opp_samples_files.h" +#include "profile_container.h" +#include "profile.h" #include "counter_util.h" #include "derive_files.h" #include "format_output.h" @@ -39,7 +39,7 @@ * * Lists all the symbols in decreasing sample count order, to standard out. */ -static void do_list_symbols(samples_container_t & samples, +static void do_list_symbols(profile_container_t const & samples, format_output::formatter & out, int sort_by_ctr) { vector<symbol_entry const *> symbols = @@ -58,7 +58,7 @@ * Lists all the samples for all the symbols, from the image specified by * abfd, in increasing order of vma, to standard out. */ -static void do_list_symbols_details(samples_container_t & samples, +static void do_list_symbols_details(profile_container_t const & samples, format_output::formatter & out, int sort_by_ctr) { vector<symbol_entry const *> symbols = @@ -77,7 +77,7 @@ * the samples for this symbol from the image * specified by abfd. */ -static void do_list_symbol(samples_container_t & samples, format_output::formatter & out) +static void do_list_symbol(profile_container_t const & samples, format_output::formatter & out) { symbol_entry const * symb = samples.find_symbol(options::symbol); if (symb == 0) { @@ -111,7 +111,7 @@ * this use the grpof format <= gcc 3.0 */ static void do_dump_gprof(op_bfd & abfd, - opp_samples_files const & samples_files, + profile_t const & samples_files, int sort_by_ctr) { static gmon_hdr hdr = { { 'g', 'm', 'o', 'n' }, GMON_VERSION, {0,0,0,},}; @@ -196,13 +196,13 @@ relative_to_absolute_path(options::sample_file, samples_dir); if (!options::gprof_file.empty()) { - opp_samples_files samples_files(options::sample_file, options::counter_mask); - samples_files.check_mtime(options::image_file); + profile_t profile(options::sample_file, options::counter_mask); + profile.check_mtime(options::image_file); op_bfd abfd(options::image_file, options::exclude_symbols, vector<string>()); - samples_files.set_start_offset(abfd.get_start_offset()); - do_dump_gprof(abfd, samples_files, options::sort_by_counter); + profile.set_start_offset(abfd.get_start_offset()); + do_dump_gprof(abfd, profile, options::sort_by_counter); return 0; } @@ -220,7 +220,7 @@ get_sample_file_list(filelist, dir, name + "}}}*"); } - samples_container_t samples(!options::list_all_symbols_details, + profile_container_t samples(!options::list_all_symbols_details, options::output_format_flags, options::counter_mask); filelist.push_front(options::sample_file); @@ -249,21 +249,21 @@ if (i == OP_MAX_COUNTERS) continue; - opp_samples_files samples_files(file, options::counter_mask); + profile_t profile(file, options::counter_mask); // the first opened file is treated specially because user can // specify the image name for this sample file on command line // we must deduce the image name from the samples file name if (it == filelist.begin()) { - opp_samples_files samples_files(file, options::counter_mask); + profile_t profile(file, options::counter_mask); op_bfd abfd(options::image_file, options::exclude_symbols, vector<string>()); - samples_files.check_mtime(options::image_file); - samples_files.set_start_offset(abfd.get_start_offset()); - samples.add(samples_files, abfd, options::symbol); + profile.check_mtime(options::image_file); + profile.set_start_offset(abfd.get_start_offset()); + samples.add(profile, abfd, options::symbol); - samples_files.output_header(); + profile.output_header(); first_file = false; } else { string app_name; Index: symbol_container_imp.cpp =================================================================== RCS file: /cvsroot/oprofile/oprofile/pp/symbol_container_imp.cpp,v retrieving revision 1.8 retrieving revision 1.9 diff -u -d -r1.8 -r1.9 --- symbol_container_imp.cpp 12 Oct 2002 04:38:21 -0000 1.8 +++ symbol_container_imp.cpp 8 Dec 2002 05:12:29 -0000 1.9 @@ -16,7 +16,7 @@ #include "symbol_functors.h" #include "symbol_container_imp.h" -#include "samples_container.h" +#include "profile_container.h" using namespace std; @@ -91,7 +91,7 @@ } void symbol_container_imp_t::get_symbols_by_count(size_t counter, - samples_container_t::symbol_collection & v) const + profile_container_t::symbol_collection & v) const { for (symbol_index_t i = 0 ; i < symbols.size() ; ++i) v.push_back(&symbols[i]); Index: symbol_container_imp.h =================================================================== RCS file: /cvsroot/oprofile/oprofile/pp/symbol_container_imp.h,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- symbol_container_imp.h 7 Sep 2002 18:19:41 -0000 1.5 +++ symbol_container_imp.h 8 Dec 2002 05:12:29 -0000 1.6 @@ -16,7 +16,7 @@ #include <string> #include <set> -#include "samples_container.h" +#include "profile_container.h" class symbol_container_imp_t { public: @@ -32,7 +32,7 @@ symbol_entry const * find_by_vma(bfd_vma vma) const; - void get_symbols_by_count(size_t counter, samples_container_t::symbol_collection& v) const; + void get_symbols_by_count(size_t counter, profile_container_t::symbol_collection& v) const; private: void build_by_file_loc() const; --- opp_samples_files.cpp DELETED --- --- opp_samples_files.h DELETED --- --- samples_container.cpp DELETED --- --- samples_container.h DELETED --- --- samples_file.cpp DELETED --- --- samples_file.h DELETED --- |