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