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