]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
common: fix a racing in PerfCounters::perf_counter_data_any_d::read_avg 23362/head
authorludehp <ludehp@163.com>
Sun, 2 Dec 2018 15:01:51 +0000 (23:01 +0800)
committerludehp <ludehp@163.com>
Sun, 2 Dec 2018 15:01:51 +0000 (23:01 +0800)
Fixes: http://tracker.ceph.com/issues/25211
Signed-off-by: ludehp <ludehp@163.com>
src/common/perf_counters.h
src/test/perf_counters.cc

index 0b9f782bc9e3d6b72ea1cbd1ae156aaceec33873..d65af189f56714610fcbb1b03f36268705b3baad 100644 (file)
@@ -204,9 +204,9 @@ public:
     pair<uint64_t,uint64_t> read_avg() const {
       uint64_t sum, count;
       do {
-       count = avgcount;
+       count = avgcount2;
        sum = u64;
-      } while (avgcount2 != count);
+      } while (avgcount != count);
       return make_pair(sum, count);
     }
   };
index 87ce7163cdeadb61570b08ce795dd736d88a5cdb..a3a5a52782b37e273da2da47d52245ad5e486ff8 100644 (file)
@@ -42,6 +42,7 @@
 #include <sys/un.h>
 #include <time.h>
 #include <unistd.h>
+#include <thread>
 
 #include "common/common_init.h"
 
@@ -219,3 +220,48 @@ TEST(PerfCounters, ResetPerfCounters) {
   ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf reset\", \"var\": \"test_perfcounter_1\", \"format\": \"json\" }", &msg));
   ASSERT_EQ(sd("{\"error\":\"Not find: test_perfcounter_1\"}"), msg);
 }
+
+enum {
+  TEST_PERFCOUNTERS3_ELEMENT_FIRST = 400,
+  TEST_PERFCOUNTERS3_ELEMENT_READ,
+  TEST_PERFCOUNTERS3_ELEMENT_LAST,
+};
+
+static std::shared_ptr<PerfCounters> setup_test_perfcounter3(CephContext* cct) {
+  PerfCountersBuilder bld(cct, "test_percounter_3",
+      TEST_PERFCOUNTERS3_ELEMENT_FIRST, TEST_PERFCOUNTERS3_ELEMENT_LAST);
+  bld.add_time_avg(TEST_PERFCOUNTERS3_ELEMENT_READ, "read_avg");
+  std::shared_ptr<PerfCounters> p(bld.create_perf_counters());
+  return p;
+}
+
+static void counters_inc_test(std::shared_ptr<PerfCounters> fake_pf) {
+  int i = 100000;
+  utime_t t;
+
+  // set to 1 nsec
+  t.set_from_double(0.000000001);
+  while (i--) {
+    // increase by one, make sure data.u64 equal to data.avgcount
+    fake_pf->tinc(TEST_PERFCOUNTERS3_ELEMENT_READ, t);
+  }
+}
+
+static void counters_readavg_test(std::shared_ptr<PerfCounters> fake_pf) {
+  int i = 100000;
+
+  while (i--) {
+    std::pair<uint64_t, uint64_t> dat = fake_pf->get_tavg_ns(TEST_PERFCOUNTERS3_ELEMENT_READ);
+    // sum and count should be identical as we increment TEST_PERCOUNTERS_ELEMENT_READ by 1 nsec eveytime
+    ASSERT_EQ(dat.first, dat.second);
+  }
+}
+
+TEST(PerfCounters, read_avg) {
+  std::shared_ptr<PerfCounters> fake_pf = setup_test_perfcounter3(g_ceph_context);
+
+  std::thread t1(counters_inc_test, fake_pf);
+  std::thread t2(counters_readavg_test, fake_pf);
+  t2.join();
+  t1.join();
+}
\ No newline at end of file