Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "dbus/dbus_statistics.h" | 5 #include "dbus/dbus_statistics.h" |
| 6 | 6 |
| 7 #include <map> | |
| 7 #include <memory> | 8 #include <memory> |
| 8 #include <set> | 9 #include <tuple> |
| 9 | 10 |
| 10 #include "base/logging.h" | 11 #include "base/logging.h" |
| 11 #include "base/macros.h" | 12 #include "base/macros.h" |
| 12 #include "base/stl_util.h" | 13 #include "base/memory/ptr_util.h" |
| 13 #include "base/strings/stringprintf.h" | 14 #include "base/strings/stringprintf.h" |
| 14 #include "base/threading/platform_thread.h" | 15 #include "base/threading/platform_thread.h" |
| 15 #include "base/time/time.h" | 16 #include "base/time/time.h" |
| 16 | 17 |
| 17 namespace dbus { | 18 namespace dbus { |
| 18 | 19 |
| 19 namespace { | 20 namespace { |
| 20 | 21 |
| 21 // Used to store dbus statistics sorted alphabetically by service, interface, | 22 // Used to store dbus statistics sorted alphabetically by service, interface, |
| 22 // then method (using std::string <). | 23 // then method (using std::string <). |
| 23 struct Stat { | 24 struct Stat { |
| 24 Stat(const std::string& service, | 25 Stat(const std::string& service, |
| 25 const std::string& interface, | 26 const std::string& interface, |
| 26 const std::string& method) | 27 const std::string& method) |
| 27 : service(service), | 28 : service(service), |
| 28 interface(interface), | 29 interface(interface), |
| 29 method(method), | 30 method(method), |
| 30 sent_method_calls(0), | 31 sent_method_calls(0), |
| 31 received_signals(0), | 32 received_signals(0), |
| 32 sent_blocking_method_calls(0) { | 33 sent_blocking_method_calls(0) { |
| 33 } | 34 } |
| 34 std::string service; | 35 std::string service; |
| 35 std::string interface; | 36 std::string interface; |
| 36 std::string method; | 37 std::string method; |
| 37 int sent_method_calls; | 38 int sent_method_calls; |
| 38 int received_signals; | 39 int received_signals; |
| 39 int sent_blocking_method_calls; | 40 int sent_blocking_method_calls; |
| 40 | 41 |
| 41 bool Compare(const Stat& other) const { | |
| 42 if (service != other.service) | |
| 43 return service < other.service; | |
| 44 if (interface != other.interface) | |
| 45 return interface < other.interface; | |
| 46 return method < other.method; | |
| 47 } | |
| 48 | |
| 49 struct PtrCompare { | 42 struct PtrCompare { |
| 50 bool operator()(Stat* lhs, Stat* rhs) const { | 43 bool operator()(Stat* lhs, Stat* rhs) const { |
| 51 DCHECK(lhs && rhs); | 44 DCHECK(lhs && rhs); |
| 52 return lhs->Compare(*rhs); | 45 return std::tie(lhs->service, lhs->interface, lhs->method) < |
| 46 std::tie(rhs->service, rhs->interface, rhs->method); | |
| 53 } | 47 } |
| 54 }; | 48 }; |
| 55 }; | 49 }; |
| 56 | 50 |
| 57 typedef std::set<Stat*, Stat::PtrCompare> StatSet; | 51 using StatSet = std::map<Stat*, std::unique_ptr<Stat>, Stat::PtrCompare>; |
|
satorux1
2016/10/11 01:29:58
why was it changed from set to map?
if it's a map
Avi (use Gerrit)
2016/10/11 16:31:46
In doing the conversions I've been switching becau
| |
| 58 | 52 |
| 59 //------------------------------------------------------------------------------ | 53 //------------------------------------------------------------------------------ |
| 60 // DBusStatistics | 54 // DBusStatistics |
| 61 | 55 |
| 62 // Simple class for gathering DBus usage statistics. | 56 // Simple class for gathering DBus usage statistics. |
| 63 class DBusStatistics { | 57 class DBusStatistics { |
| 64 public: | 58 public: |
| 65 DBusStatistics() | 59 DBusStatistics() |
| 66 : start_time_(base::Time::Now()), | 60 : start_time_(base::Time::Now()), |
| 67 origin_thread_id_(base::PlatformThread::CurrentId()) { | 61 origin_thread_id_(base::PlatformThread::CurrentId()) { |
| 68 } | 62 } |
| 69 | 63 |
| 70 ~DBusStatistics() { | 64 ~DBusStatistics() { |
| 71 DCHECK_EQ(origin_thread_id_, base::PlatformThread::CurrentId()); | 65 DCHECK_EQ(origin_thread_id_, base::PlatformThread::CurrentId()); |
| 72 base::STLDeleteContainerPointers(stats_.begin(), stats_.end()); | |
| 73 } | 66 } |
| 74 | 67 |
| 75 // Enum to specify which field in Stat to increment in AddStat | 68 // Enum to specify which field in Stat to increment in AddStat |
| 76 enum StatType { | 69 enum StatType { |
| 77 TYPE_SENT_METHOD_CALLS, | 70 TYPE_SENT_METHOD_CALLS, |
| 78 TYPE_RECEIVED_SIGNALS, | 71 TYPE_RECEIVED_SIGNALS, |
| 79 TYPE_SENT_BLOCKING_METHOD_CALLS | 72 TYPE_SENT_BLOCKING_METHOD_CALLS |
| 80 }; | 73 }; |
| 81 | 74 |
| 82 // Add a call to |method| for |interface|. See also MethodCall in message.h. | 75 // Add a call to |method| for |interface|. See also MethodCall in message.h. |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 101 NOTREACHED(); | 94 NOTREACHED(); |
| 102 } | 95 } |
| 103 | 96 |
| 104 // Look up the Stat entry in |stats_|. If |add_stat| is true, add a new entry | 97 // Look up the Stat entry in |stats_|. If |add_stat| is true, add a new entry |
| 105 // if one does not already exist. | 98 // if one does not already exist. |
| 106 Stat* GetStat(const std::string& service, | 99 Stat* GetStat(const std::string& service, |
| 107 const std::string& interface, | 100 const std::string& interface, |
| 108 const std::string& method, | 101 const std::string& method, |
| 109 bool add_stat) { | 102 bool add_stat) { |
| 110 DCHECK_EQ(origin_thread_id_, base::PlatformThread::CurrentId()); | 103 DCHECK_EQ(origin_thread_id_, base::PlatformThread::CurrentId()); |
| 111 std::unique_ptr<Stat> stat(new Stat(service, interface, method)); | 104 std::unique_ptr<Stat> stat = |
| 112 StatSet::iterator found = stats_.find(stat.get()); | 105 base::MakeUnique<Stat>(service, interface, method); |
| 106 auto found = stats_.find(stat.get()); | |
| 113 if (found != stats_.end()) | 107 if (found != stats_.end()) |
| 114 return *found; | 108 return found->first; |
| 115 if (!add_stat) | 109 if (!add_stat) |
| 116 return NULL; | 110 return nullptr; |
| 117 found = stats_.insert(stat.release()).first; | 111 Stat* stat_ptr = stat.get(); |
| 118 return *found; | 112 stats_[stat_ptr] = std::move(stat); |
| 113 return stat_ptr; | |
| 119 } | 114 } |
| 120 | 115 |
| 121 StatSet& stats() { return stats_; } | 116 StatSet& stats() { return stats_; } |
| 122 base::Time start_time() { return start_time_; } | 117 base::Time start_time() { return start_time_; } |
| 123 | 118 |
| 124 private: | 119 private: |
| 125 StatSet stats_; | 120 StatSet stats_; |
| 126 base::Time start_time_; | 121 base::Time start_time_; |
| 127 base::PlatformThreadId origin_thread_id_; | 122 base::PlatformThreadId origin_thread_id_; |
| 128 | 123 |
| 129 DISALLOW_COPY_AND_ASSIGN(DBusStatistics); | 124 DISALLOW_COPY_AND_ASSIGN(DBusStatistics); |
| 130 }; | 125 }; |
| 131 | 126 |
| 132 DBusStatistics* g_dbus_statistics = NULL; | 127 DBusStatistics* g_dbus_statistics = nullptr; |
| 133 | 128 |
| 134 } // namespace | 129 } // namespace |
| 135 | 130 |
| 136 //------------------------------------------------------------------------------ | 131 //------------------------------------------------------------------------------ |
| 137 | 132 |
| 138 namespace statistics { | 133 namespace statistics { |
| 139 | 134 |
| 140 void Initialize() { | 135 void Initialize() { |
| 141 if (g_dbus_statistics) | 136 if (g_dbus_statistics) |
| 142 delete g_dbus_statistics; // reset statistics | 137 delete g_dbus_statistics; // reset statistics |
| 143 g_dbus_statistics = new DBusStatistics(); | 138 g_dbus_statistics = new DBusStatistics(); |
| 144 } | 139 } |
| 145 | 140 |
| 146 void Shutdown() { | 141 void Shutdown() { |
| 147 delete g_dbus_statistics; | 142 delete g_dbus_statistics; |
| 148 g_dbus_statistics = NULL; | 143 g_dbus_statistics = nullptr; |
| 149 } | 144 } |
| 150 | 145 |
| 151 void AddSentMethodCall(const std::string& service, | 146 void AddSentMethodCall(const std::string& service, |
| 152 const std::string& interface, | 147 const std::string& interface, |
| 153 const std::string& method) { | 148 const std::string& method) { |
| 154 if (!g_dbus_statistics) | 149 if (!g_dbus_statistics) |
| 155 return; | 150 return; |
| 156 g_dbus_statistics->AddStat( | 151 g_dbus_statistics->AddStat( |
| 157 service, interface, method, DBusStatistics::TYPE_SENT_METHOD_CALLS); | 152 service, interface, method, DBusStatistics::TYPE_SENT_METHOD_CALLS); |
| 158 } | 153 } |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 186 if (stats.empty()) | 181 if (stats.empty()) |
| 187 return "No DBus calls."; | 182 return "No DBus calls."; |
| 188 | 183 |
| 189 base::TimeDelta dtime = base::Time::Now() - g_dbus_statistics->start_time(); | 184 base::TimeDelta dtime = base::Time::Now() - g_dbus_statistics->start_time(); |
| 190 int dminutes = dtime.InMinutes(); | 185 int dminutes = dtime.InMinutes(); |
| 191 dminutes = std::max(dminutes, 1); | 186 dminutes = std::max(dminutes, 1); |
| 192 | 187 |
| 193 std::string result; | 188 std::string result; |
| 194 int sent = 0, received = 0, sent_blocking = 0; | 189 int sent = 0, received = 0, sent_blocking = 0; |
| 195 // Stats are stored in order by service, then interface, then method. | 190 // Stats are stored in order by service, then interface, then method. |
| 196 for (StatSet::const_iterator iter = stats.begin(); iter != stats.end(); ) { | 191 for (auto iter = stats.begin(); iter != stats.end();) { |
| 197 StatSet::const_iterator cur_iter = iter; | 192 auto cur_iter = iter; |
| 198 StatSet::const_iterator next_iter = ++iter; | 193 auto next_iter = ++iter; |
| 199 const Stat* stat = *cur_iter; | 194 const Stat* stat = cur_iter->first; |
| 200 sent += stat->sent_method_calls; | 195 sent += stat->sent_method_calls; |
| 201 received += stat->received_signals; | 196 received += stat->received_signals; |
| 202 sent_blocking += stat->sent_blocking_method_calls; | 197 sent_blocking += stat->sent_blocking_method_calls; |
| 203 // If this is not the last stat, and if the next stat matches the current | 198 // If this is not the last stat, and if the next stat matches the current |
| 204 // stat, continue. | 199 // stat, continue. |
| 205 if (next_iter != stats.end() && | 200 if (next_iter != stats.end() && |
| 206 (*next_iter)->service == stat->service && | 201 next_iter->first->service == stat->service && |
| 207 (show < SHOW_INTERFACE || (*next_iter)->interface == stat->interface) && | 202 (show < SHOW_INTERFACE || |
| 208 (show < SHOW_METHOD || (*next_iter)->method == stat->method)) | 203 next_iter->first->interface == stat->interface) && |
| 204 (show < SHOW_METHOD || next_iter->first->method == stat->method)) | |
| 209 continue; | 205 continue; |
| 210 | 206 |
| 211 if (!sent && !received && !sent_blocking) | 207 if (!sent && !received && !sent_blocking) |
| 212 continue; // No stats collected for this line, skip it and continue. | 208 continue; // No stats collected for this line, skip it and continue. |
| 213 | 209 |
| 214 // Add a line to the result and clear the counts. | 210 // Add a line to the result and clear the counts. |
| 215 std::string line; | 211 std::string line; |
| 216 if (show == SHOW_SERVICE) { | 212 if (show == SHOW_SERVICE) { |
| 217 line += stat->service; | 213 line += stat->service; |
| 218 } else { | 214 } else { |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 275 *sent = stat->sent_method_calls; | 271 *sent = stat->sent_method_calls; |
| 276 *received = stat->received_signals; | 272 *received = stat->received_signals; |
| 277 *blocking = stat->sent_blocking_method_calls; | 273 *blocking = stat->sent_blocking_method_calls; |
| 278 return true; | 274 return true; |
| 279 } | 275 } |
| 280 | 276 |
| 281 } // namespace testing | 277 } // namespace testing |
| 282 | 278 |
| 283 } // namespace statistics | 279 } // namespace statistics |
| 284 } // namespace dbus | 280 } // namespace dbus |
| OLD | NEW |