Belle II Software development
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
25void 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
48std::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
80int 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