]> git.proxmox.com Git - ceph.git/blob - ceph/src/common/mempool.cc
import ceph quincy 17.2.6
[ceph.git] / ceph / src / common / mempool.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 /*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2016 Allen Samuels <allen.samuels@sandisk.com>
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 *
13 */
14
15 #include "include/mempool.h"
16 #include "include/demangle.h"
17
18
19 // default to debug_mode off
20 bool mempool::debug_mode = false;
21
22 // --------------------------------------------------------------
23
24 mempool::pool_t& mempool::get_pool(mempool::pool_index_t ix)
25 {
26 // We rely on this array being initialized before any invocation of
27 // this function, even if it is called by ctors in other compilation
28 // units that are being initialized before this compilation unit.
29 static mempool::pool_t table[num_pools];
30 return table[ix];
31 }
32
33 const char *mempool::get_pool_name(mempool::pool_index_t ix) {
34 #define P(x) #x,
35 static const char *names[num_pools] = {
36 DEFINE_MEMORY_POOLS_HELPER(P)
37 };
38 #undef P
39 return names[ix];
40 }
41
42 void mempool::dump(ceph::Formatter *f)
43 {
44 stats_t total;
45 f->open_object_section("mempool"); // we need (dummy?) topmost section for
46 // JSON Formatter to print pool names. It omits them otherwise.
47 f->open_object_section("by_pool");
48 for (size_t i = 0; i < num_pools; ++i) {
49 const pool_t &pool = mempool::get_pool((pool_index_t)i);
50 f->open_object_section(get_pool_name((pool_index_t)i));
51 pool.dump(f, &total);
52 f->close_section();
53 }
54 f->close_section();
55 f->dump_object("total", total);
56 f->close_section();
57 }
58
59 void mempool::set_debug_mode(bool d)
60 {
61 debug_mode = d;
62 }
63
64 // --------------------------------------------------------------
65 // pool_t
66
67 size_t mempool::pool_t::allocated_bytes() const
68 {
69 ssize_t result = 0;
70 for (size_t i = 0; i < num_shards; ++i) {
71 result += shard[i].bytes;
72 }
73 if (result < 0) {
74 // we raced with some unbalanced allocations/deallocations
75 result = 0;
76 }
77 return (size_t) result;
78 }
79
80 size_t mempool::pool_t::allocated_items() const
81 {
82 ssize_t result = 0;
83 for (size_t i = 0; i < num_shards; ++i) {
84 result += shard[i].items;
85 }
86 if (result < 0) {
87 // we raced with some unbalanced allocations/deallocations
88 result = 0;
89 }
90 return (size_t) result;
91 }
92
93 void mempool::pool_t::adjust_count(ssize_t items, ssize_t bytes)
94 {
95 shard_t *shard = pick_a_shard();
96 shard->items += items;
97 shard->bytes += bytes;
98 }
99
100 void mempool::pool_t::get_stats(
101 stats_t *total,
102 std::map<std::string, stats_t> *by_type) const
103 {
104 for (size_t i = 0; i < num_shards; ++i) {
105 total->items += shard[i].items;
106 total->bytes += shard[i].bytes;
107 }
108 if (debug_mode) {
109 std::lock_guard shard_lock(lock);
110 for (auto &p : type_map) {
111 std::string n = ceph_demangle(p.second.type_name);
112 stats_t &s = (*by_type)[n];
113 s.bytes = p.second.items * p.second.item_size;
114 s.items = p.second.items;
115 }
116 }
117 }
118
119 void mempool::pool_t::dump(ceph::Formatter *f, stats_t *ptotal) const
120 {
121 stats_t total;
122 std::map<std::string, stats_t> by_type;
123 get_stats(&total, &by_type);
124 if (ptotal) {
125 *ptotal += total;
126 }
127 total.dump(f);
128 if (!by_type.empty()) {
129 f->open_object_section("by_type");
130 for (auto &i : by_type) {
131 f->open_object_section(i.first.c_str());
132 i.second.dump(f);
133 f->close_section();
134 }
135 f->close_section();
136 }
137 }