1 // Copyright 2015 Google Inc. All rights reserved
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 // +build ignore
16 
17 #include "stats.h"
18 
19 #include <mutex>
20 #include <vector>
21 
22 #include "flags.h"
23 #include "log.h"
24 #include "stringprintf.h"
25 #include "thread_local.h"
26 #include "timeutil.h"
27 
28 namespace {
29 
30 mutex g_mu;
31 vector<Stats*>* g_stats;
32 DEFINE_THREAD_LOCAL(double, g_start_time);
33 
34 }  // namespace
35 
Stats(const char * name)36 Stats::Stats(const char* name)
37     : name_(name), elapsed_(0), cnt_(0) {
38   unique_lock<mutex> lock(g_mu);
39   if (g_stats == NULL)
40     g_stats = new vector<Stats*>;
41   g_stats->push_back(this);
42 }
43 
String() const44 string Stats::String() const {
45   unique_lock<mutex> lock(mu_);
46   return StringPrintf("%s: %f / %d", name_, elapsed_, cnt_);
47 }
48 
Start()49 void Stats::Start() {
50   CHECK(!TLS_REF(g_start_time));
51   TLS_REF(g_start_time) = GetTime();
52   unique_lock<mutex> lock(mu_);
53   cnt_++;
54 }
55 
End()56 double Stats::End() {
57   CHECK(TLS_REF(g_start_time));
58   double e = GetTime() - TLS_REF(g_start_time);
59   TLS_REF(g_start_time) = 0;
60   unique_lock<mutex> lock(mu_);
61   elapsed_ += e;
62   return e;
63 }
64 
ScopedStatsRecorder(Stats * st,const char * msg)65 ScopedStatsRecorder::ScopedStatsRecorder(Stats* st, const char* msg)
66     : st_(st), msg_(msg) {
67   if (!g_flags.enable_stat_logs)
68     return;
69   st_->Start();
70 }
71 
~ScopedStatsRecorder()72 ScopedStatsRecorder::~ScopedStatsRecorder() {
73   if (!g_flags.enable_stat_logs)
74     return;
75   double e = st_->End();
76   if (msg_ && e > 3.0) {
77     LOG_STAT("slow %s (%f): %s", st_->name_, e, msg_);
78   }
79 }
80 
ReportAllStats()81 void ReportAllStats() {
82   if (!g_stats)
83     return;
84   for (Stats* st : *g_stats) {
85     LOG_STAT("%s", st->String().c_str());
86   }
87   delete g_stats;
88 }
89