Belle II Software  release-05-01-25
framework-pcore-monitor_ringbuffers.cc
1 #include <framework/pcore/RingBuffer.h>
2 #include <framework/logging/Logger.h>
3 
4 #include <iostream>
5 #include <iomanip>
6 
7 #include <dirent.h>
8 #include <cstdio>
9 #include <unistd.h>
10 #include <cstring>
11 
12 #include <sys/ipc.h>
13 #include <sys/shm.h>
14 
15 
16 void rbinfo(int shmid)
17 {
18  const int* shmadr = (int*) shmat(shmid, nullptr, SHM_RDONLY);
19  if (shmadr == (int*) - 1) {
20  B2FATAL("RingBuffer: Attaching to shared memory segment via shmat() failed");
21  }
22  const auto* m_bufinfo = reinterpret_cast<const Belle2::RingBufInfo*>(shmadr);
23 
24  long filled_bytes = m_bufinfo->wptr - m_bufinfo->rptr;
25  if (filled_bytes < 0)
26  filled_bytes += m_bufinfo->size;
27  filled_bytes *= sizeof(int); //weird size unit
28  double filled_MB = (filled_bytes) / 1024.0 / 1024.0;
29  std::cout << "RB " << shmid
30  << " #Tx: " << m_bufinfo->numAttachedTx << "\t"
31  << " #busy: " << m_bufinfo->nbusy << "\t"
32  << m_bufinfo->nbuf << " entries\t"
33  << filled_MB << " MiB filled\t(" << 100.0 * filled_bytes / double(m_bufinfo->size * sizeof(int)) << " %)"
34  << "\n";
35 
36  shmdt(shmadr);
37 }
38 
39 std::vector<int> findRingBuffers()
40 {
41  std::vector<int> buffer_SHMs;
42  DIR* dir;
43  if ((dir = opendir("/tmp")) != nullptr) {
44  struct dirent* ent;
45  while ((ent = readdir(dir)) != nullptr) {
46  if (strncmp(ent->d_name, "SHM", 3) == 0) {
47  int shmid, semid;
48  char name[256];
49  sscanf(ent->d_name, "SHM%d-SEM%d-%255s", &shmid, &semid, name);
50  if (shmid > 0) {
51  shmid_ds shmInfo;
52  if (shmctl(shmid, IPC_STAT, &shmInfo) == 0) {
53  //only use SHM segments which still have a process attached
54  //Note that nattch counter is decreased by both shmdt() and exit()
55  if (shmInfo.shm_nattch != 0) {
56  buffer_SHMs.push_back(shmid);
57  }
58  }
59  }
60  }
61  }
62 
63  closedir(dir);
64  } else {
65  perror("");
66  }
67  return buffer_SHMs;
68 }
69 
70 
71 int main(int argc, char**)
72 {
73  if (argc > 1) {
74  printf("Usage : monitor_ringbuffers\n");
75 
76  printf("\n Shows fill-state information on all active RingBuffers on this system.\n\n");
77  return -1;
78  }
79 
80  std::cout << std::setprecision(2) << std::fixed;
81  while (true) {
82  std::vector<int> buffer_SHMs = findRingBuffers();
83  if (buffer_SHMs.empty())
84  break;
85  for (int shmid : buffer_SHMs)
86  rbinfo(shmid);
87  std::cout << "\n";
88  usleep(100000);
89  }
90  std::cout << "No Ringbuffers found, exiting.\n";
91 
92  return 0;
93 }
Belle2::RingBufInfo
Internal metadata structure for RingBuffer.
Definition: RingBuffer.h:18
main
int main(int argc, char **argv)
Run all tests.
Definition: test_main.cc:77
Belle2::RingBufInfo::wptr
int wptr
Pointer for writing entries.
Definition: RingBuffer.h:21