summaryrefslogtreecommitdiff
path: root/src/common/MemoryModel.cc
blob: 8b2e36721b6b7da1faf171939e4463ed714c5c3a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include "include/types.h"

#include <fstream>

#include "common/config.h"
#include "common/debug.h"

#include "MemoryModel.h"

#define dout_subsys ceph_subsys_

MemoryModel::MemoryModel(CephContext *cct_)
  : cct(cct_)
{
}

void MemoryModel::_sample(snap *psnap)
{
  ifstream f;

  f.open("/proc/self/status");
  if (!f.is_open()) {
    ldout(cct, 0) << "check_memory_usage unable to open /proc/self/status" << dendl;
    return;
  }

  while (!f.eof()) {
    string line;
    getline(f, line);
    
    if (strncmp(line.c_str(), "VmSize:", 7) == 0)
      psnap->size = atoi(line.c_str() + 7);
    else if (strncmp(line.c_str(), "VmRSS:", 6) == 0)
      psnap->rss = atoi(line.c_str() + 7);
    else if (strncmp(line.c_str(), "VmHWM:", 6) == 0)
      psnap->hwm = atoi(line.c_str() + 7);
    else if (strncmp(line.c_str(), "VmLib:", 6) == 0)
      psnap->lib = atoi(line.c_str() + 7);
    else if (strncmp(line.c_str(), "VmPeak:", 7) == 0)
      psnap->peak = atoi(line.c_str() + 7);
    else if (strncmp(line.c_str(), "VmData:", 7) == 0)
      psnap->data = atoi(line.c_str() + 7);
  }
  f.close();

  f.open("/proc/self/maps");
  if (!f.is_open()) {
    ldout(cct, 0) << "check_memory_usage unable to open /proc/self/maps" << dendl;
    return;
  }

  int heap = 0;
  while (f.is_open() && !f.eof()) {
    string line;
    getline(f, line);
    //ldout(cct, 0) << "line is " << line << dendl;

    const char *start = line.c_str();
    const char *dash = start;
    while (*dash && *dash != '-') dash++;
    if (!*dash)
      continue;
    const char *end = dash + 1;
    while (*end && *end != ' ') end++;
    if (!*end)
      continue;
    unsigned long long as = strtoll(start, 0, 16);
    unsigned long long ae = strtoll(dash+1, 0, 16);

    //ldout(cct, 0) << std::hex << as << " to " << ae << std::dec << dendl;

    end++;
    const char *mode = end;

    int skip = 4;
    while (skip--) {
      end++;
      while (*end && *end != ' ') end++;
    }
    if (*end)
      end++;

    int size = ae - as;
    //ldout(cct, 0) << "size " << size << " mode is '" << mode << "' end is '" << end << "'" << dendl;

    /*
     * anything 'rw' and anon is assumed to be heap.
     */
    if (mode[0] == 'r' && mode[1] == 'w' && !*end)
      heap += size;
  }

  psnap->heap = heap >> 10;

  // ...
#if defined(__linux__)
  struct mallinfo mi = mallinfo();
  
  psnap->malloc = mi.uordblks >> 10;
  psnap->mmap = mi.hblks >> 10;
  

  ofstream log("/tmp/memlog", ios::app);
  log << "heap " << heap
      << "\trss " << psnap->rss
      << "\tmi\t" << mi.arena
      << "\t" << mi.ordblks
      << "\t" << mi.uordblks / 1024
      << "\t" << mi.fordblks / 1024
      << "\t" << mi.hblks 
      << "\t" << mi.hblkhd / 1024
      << std::endl;
#else
#warning "Not implemented!"
#endif
}