]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
common/perf_counters: use atomics instead of a mutex
authorSage Weil <sage@inktank.com>
Sun, 11 May 2014 18:18:36 +0000 (11:18 -0700)
committerSage Weil <sage@inktank.com>
Sun, 11 May 2014 18:18:36 +0000 (11:18 -0700)
The mutex is way too expensive.

Signed-off-by: Sage Weil <sage@inktank.com>
src/common/perf_counters.cc
src/common/perf_counters.h

index 4fe1354fa637529b83b435382235ad660b5cb412..06edb41991038bfa4d59c4e56f013db9fa33cda3 100644 (file)
@@ -101,15 +101,14 @@ void PerfCounters::inc(int idx, uint64_t amt)
   if (!m_cct->_conf->perf)
     return;
 
-  Mutex::Locker lck(m_lock);
   assert(idx > m_lower_bound);
   assert(idx < m_upper_bound);
   perf_counter_data_any_d& data(m_data[idx - m_lower_bound - 1]);
   if (!(data.type & PERFCOUNTER_U64))
     return;
-  data.u64 += amt;
+  data.u64.add(amt);
   if (data.type & PERFCOUNTER_LONGRUNAVG)
-    data.avgcount++;
+    data.avgcount.inc();
 }
 
 void PerfCounters::dec(int idx, uint64_t amt)
@@ -117,15 +116,13 @@ void PerfCounters::dec(int idx, uint64_t amt)
   if (!m_cct->_conf->perf)
     return;
 
-  Mutex::Locker lck(m_lock);
   assert(idx > m_lower_bound);
   assert(idx < m_upper_bound);
   perf_counter_data_any_d& data(m_data[idx - m_lower_bound - 1]);
   assert(!(data.type & PERFCOUNTER_LONGRUNAVG));
   if (!(data.type & PERFCOUNTER_U64))
     return;
-  assert(data.u64 >= amt);
-  data.u64 -= amt;
+  data.u64.sub(amt);
 }
 
 void PerfCounters::set(int idx, uint64_t amt)
@@ -133,15 +130,14 @@ void PerfCounters::set(int idx, uint64_t amt)
   if (!m_cct->_conf->perf)
     return;
 
-  Mutex::Locker lck(m_lock);
   assert(idx > m_lower_bound);
   assert(idx < m_upper_bound);
   perf_counter_data_any_d& data(m_data[idx - m_lower_bound - 1]);
   if (!(data.type & PERFCOUNTER_U64))
     return;
-  data.u64 = amt;
+  data.u64.set(amt);
   if (data.type & PERFCOUNTER_LONGRUNAVG)
-    data.avgcount++;
+    data.avgcount.inc();
 }
 
 uint64_t PerfCounters::get(int idx) const
@@ -149,13 +145,12 @@ uint64_t PerfCounters::get(int idx) const
   if (!m_cct->_conf->perf)
     return 0;
 
-  Mutex::Locker lck(m_lock);
   assert(idx > m_lower_bound);
   assert(idx < m_upper_bound);
   const perf_counter_data_any_d& data(m_data[idx - m_lower_bound - 1]);
   if (!(data.type & PERFCOUNTER_U64))
     return 0;
-  return data.u64;
+  return data.u64.read();
 }
 
 void PerfCounters::tinc(int idx, utime_t amt)
@@ -163,15 +158,14 @@ void PerfCounters::tinc(int idx, utime_t amt)
   if (!m_cct->_conf->perf)
     return;
 
-  Mutex::Locker lck(m_lock);
   assert(idx > m_lower_bound);
   assert(idx < m_upper_bound);
   perf_counter_data_any_d& data(m_data[idx - m_lower_bound - 1]);
   if (!(data.type & PERFCOUNTER_TIME))
     return;
-  data.u64 += amt.to_nsec();
+  data.u64.add(amt.to_nsec());
   if (data.type & PERFCOUNTER_LONGRUNAVG)
-    data.avgcount++;
+    data.avgcount.inc();
 }
 
 void PerfCounters::tset(int idx, utime_t amt)
@@ -179,13 +173,12 @@ void PerfCounters::tset(int idx, utime_t amt)
   if (!m_cct->_conf->perf)
     return;
 
-  Mutex::Locker lck(m_lock);
   assert(idx > m_lower_bound);
   assert(idx < m_upper_bound);
   perf_counter_data_any_d& data(m_data[idx - m_lower_bound - 1]);
   if (!(data.type & PERFCOUNTER_TIME))
     return;
-  data.u64 = amt.to_nsec();
+  data.u64.set(amt.to_nsec());
   if (data.type & PERFCOUNTER_LONGRUNAVG)
     assert(0);
 }
@@ -195,13 +188,13 @@ utime_t PerfCounters::tget(int idx) const
   if (!m_cct->_conf->perf)
     return utime_t();
 
-  Mutex::Locker lck(m_lock);
   assert(idx > m_lower_bound);
   assert(idx < m_upper_bound);
   const perf_counter_data_any_d& data(m_data[idx - m_lower_bound - 1]);
   if (!(data.type & PERFCOUNTER_TIME))
     return utime_t();
-  return utime_t(data.u64 / 1000000000ull, data.u64 % 1000000000ull);
+  uint64_t v = data.u64.read();
+  return utime_t(v / 1000000000ull, v % 1000000000ull);
 }
 
 pair<uint64_t, uint64_t> PerfCounters::get_tavg_ms(int idx) const
@@ -209,7 +202,6 @@ pair<uint64_t, uint64_t> PerfCounters::get_tavg_ms(int idx) const
   if (!m_cct->_conf->perf)
     return make_pair(0, 0);
 
-  Mutex::Locker lck(m_lock);
   assert(idx > m_lower_bound);
   assert(idx < m_upper_bound);
   const perf_counter_data_any_d& data(m_data[idx - m_lower_bound - 1]);
@@ -217,13 +209,11 @@ pair<uint64_t, uint64_t> PerfCounters::get_tavg_ms(int idx) const
     return make_pair(0, 0);
   if (!(data.type & PERFCOUNTER_LONGRUNAVG))
     return make_pair(0, 0);
-  return make_pair(data.avgcount, data.u64/1000000);
+  return make_pair(data.avgcount.read(), data.u64.read()/1000000);
 }
 
 void PerfCounters::dump_formatted(Formatter *f, bool schema)
 {
-  Mutex::Locker lck(m_lock);
-
   f->open_object_section(m_name.c_str());
   perf_counter_data_vec_t::const_iterator d = m_data.begin();
   perf_counter_data_vec_t::const_iterator d_end = m_data.end();
@@ -240,24 +230,26 @@ void PerfCounters::dump_formatted(Formatter *f, bool schema)
       if (d->type & PERFCOUNTER_LONGRUNAVG) {
        f->open_object_section(d->name);
        if (d->type & PERFCOUNTER_U64) {
-         f->dump_unsigned("avgcount", d->avgcount);
-         f->dump_unsigned("sum", d->u64);
+         f->dump_unsigned("avgcount", d->avgcount.read());
+         f->dump_unsigned("sum", d->u64.read());
        } else if (d->type & PERFCOUNTER_TIME) {
-         f->dump_unsigned("avgcount", d->avgcount);
+         f->dump_unsigned("avgcount", d->avgcount.read());
+         uint64_t v = d->u64.read();
          f->dump_format_unquoted("sum", "%"PRId64".%09"PRId64,
-                                 d->u64 / 1000000000ull,
-                                 d->u64 % 1000000000ull);
+                                 v / 1000000000ull,
+                                 v % 1000000000ull);
        } else {
          assert(0);
        }
        f->close_section();
       } else {
+       uint64_t v = d->u64.read();
        if (d->type & PERFCOUNTER_U64) {
-         f->dump_unsigned(d->name, d->u64);
+         f->dump_unsigned(d->name, v);
        } else if (d->type & PERFCOUNTER_TIME) {
          f->dump_format_unquoted(d->name, "%"PRId64".%09"PRId64,
-                                 d->u64 / 1000000000ull,
-                                 d->u64 % 1000000000ull);
+                                 v / 1000000000ull,
+                                 v % 1000000000ull);
        } else {
          assert(0);
        }
@@ -287,14 +279,6 @@ PerfCounters::PerfCounters(CephContext *cct, const std::string &name,
   m_data.resize(upper_bound - lower_bound - 1);
 }
 
-PerfCounters::perf_counter_data_any_d::perf_counter_data_any_d()
-  : name(NULL),
-    type(PERFCOUNTER_NONE),
-    u64(0),
-    avgcount(0)
-{
-}
-
 PerfCountersBuilder::PerfCountersBuilder(CephContext *cct, const std::string &name,
                   int first, int last)
   : m_perf_counters(new PerfCounters(cct, name, first, last))
index f4651c69f1ca97da6b697765a8aa68f91181c591..f4f650771bccbc40a82c51addce7e144e119d7b4 100644 (file)
@@ -111,14 +111,34 @@ private:
 
   /** Represents a PerfCounters data element. */
   struct perf_counter_data_any_d {
-    perf_counter_data_any_d();
+    perf_counter_data_any_d()
+      : name(NULL),
+       type(PERFCOUNTER_NONE),
+       u64(0),
+       avgcount(0)
+    {}
+    perf_counter_data_any_d(const perf_counter_data_any_d& other)
+      : name(other.name),
+       type(other.type),
+       u64(other.u64.read()),
+       avgcount(other.avgcount.read())
+    {}
+
     void write_schema_json(char *buf, size_t buf_sz) const;
     void  write_json(char *buf, size_t buf_sz) const;
 
     const char *name;
     enum perfcounter_type_d type;
-    uint64_t u64;
-    uint64_t avgcount;
+    atomic64_t u64;
+    atomic64_t avgcount;
+
+    perf_counter_data_any_d& operator=(const perf_counter_data_any_d& other) {
+      name = other.name;
+      type = other.type;
+      u64.set(other.u64.read());
+      avgcount.set(other.avgcount.read());
+      return *this;
+    }
   };
   typedef std::vector<perf_counter_data_any_d> perf_counter_data_vec_t;