profile.cpp
Go to the documentation of this file.00001
00013 #include <unistd.h>
00014 #include <cstring>
00015
00016 #include <iostream>
00017 #include <string>
00018 #include <sstream>
00019 #include <cstring>
00020
00021 #include <cerrno>
00022
00023 #include "op_exception.h"
00024 #include "op_header.h"
00025 #include "op_config.h"
00026 #include "op_sample_file.h"
00027 #include "profile.h"
00028 #include "op_bfd.h"
00029 #include "cverb.h"
00030 #include "populate_for_spu.h"
00031
00032 using namespace std;
00033
00034 profile_t::profile_t()
00035 : start_offset(0)
00036 {
00037 }
00038
00039
00040
00041 count_type profile_t::sample_count(string const & filename)
00042 {
00043 odb_t samples_db;
00044
00045 open_sample_file(filename, samples_db);
00046
00047 count_type count = 0;
00048
00049 odb_node_nr_t node_nr, pos;
00050 odb_node_t * node = odb_get_iterator(&samples_db, &node_nr);
00051 for (pos = 0; pos < node_nr; ++pos)
00052 count += node[pos].value;
00053
00054 odb_close(&samples_db);
00055
00056 return count;
00057 }
00058
00059
00060 enum profile_type profile_t::is_spu_sample_file(string const & filename)
00061 {
00062 profile_type retval;
00063 odb_t samples_db;
00064 open_sample_file(filename, samples_db);
00065 opd_header const & hdr =
00066 *static_cast<opd_header *>(odb_get_data(&samples_db));
00067 retval = hdr.spu_profile ? cell_spu_profile: normal_profile;
00068 odb_close(&samples_db);
00069 return retval;
00070 }
00071
00072
00073 void profile_t::open_sample_file(string const & filename, odb_t & db)
00074 {
00075
00076
00077 opd_header head = read_header(filename);
00078
00079 if (head.version != OPD_VERSION) {
00080 ostringstream os;
00081 os << "oprofpp: samples files version mismatch, are you "
00082 << "running a daemon and post-profile tools with version "
00083 << "mismatch ?\n";
00084 throw op_fatal_error(os.str());
00085 }
00086
00087 int rc = odb_open(&db, filename.c_str(), ODB_RDONLY,
00088 sizeof(struct opd_header));
00089
00090 if (rc)
00091 throw op_fatal_error(filename + ": " + strerror(rc));
00092 }
00093
00094 void profile_t::add_sample_file(string const & filename)
00095 {
00096 odb_t samples_db;
00097
00098 open_sample_file(filename, samples_db);
00099
00100 opd_header const & head =
00101 *static_cast<opd_header *>(odb_get_data(&samples_db));
00102
00103
00104 if (file_header.get())
00105 op_check_header(head, *file_header, filename);
00106 else
00107 file_header.reset(new opd_header(head));
00108
00109 odb_node_nr_t node_nr, pos;
00110 odb_node_t * node = odb_get_iterator(&samples_db, &node_nr);
00111
00112 for (pos = 0; pos < node_nr; ++pos) {
00113 ordered_samples_t::iterator it =
00114 ordered_samples.find(node[pos].key);
00115 if (it != ordered_samples.end()) {
00116 it->second += node[pos].value;
00117 } else {
00118 ordered_samples_t::value_type
00119 val(node[pos].key, node[pos].value);
00120 ordered_samples.insert(val);
00121 }
00122 }
00123
00124 odb_close(&samples_db);
00125 }
00126
00127
00128 void profile_t::set_offset(op_bfd const & abfd)
00129 {
00130
00131
00132
00133
00134 if (abfd.valid()) {
00135 opd_header const & header = get_header();
00136 if (header.anon_start) {
00137 start_offset = header.anon_start;
00138 } else if (header.is_kernel) {
00139 start_offset = abfd.get_start_offset(0);
00140 }
00141 }
00142 cverb << (vdebug) << "start_offset is now " << start_offset << endl;
00143 }
00144
00145
00146 profile_t::iterator_pair
00147 profile_t::samples_range(odb_key_t start, odb_key_t end) const
00148 {
00149
00150
00151
00152
00153
00154 if (start < start_offset) {
00155 return make_pair(const_iterator(ordered_samples.end(), 0),
00156 const_iterator(ordered_samples.end(), 0));
00157 }
00158
00159 start -= start_offset;
00160 end -= start_offset;
00161
00162
00163 if (start > end) {
00164 throw op_fatal_error("profile_t::samples_range(): start > end"
00165 " something wrong with kernel or module layout ?\n"
00166 "please report problem to "
00167 "oprofile-list@lists.sourceforge.net");
00168 }
00169
00170 ordered_samples_t::const_iterator first =
00171 ordered_samples.lower_bound(start);
00172 ordered_samples_t::const_iterator last =
00173 ordered_samples.lower_bound(end);
00174
00175 return make_pair(const_iterator(first, start_offset),
00176 const_iterator(last, start_offset));
00177 }
00178
00179
00180 profile_t::iterator_pair profile_t::samples_range() const
00181 {
00182 ordered_samples_t::const_iterator first = ordered_samples.begin();
00183 ordered_samples_t::const_iterator last = ordered_samples.end();
00184
00185 return make_pair(const_iterator(first, start_offset),
00186 const_iterator(last, start_offset));
00187 }