Belle II Software  release-06-02-00
HistMemory.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 #include "dqm/analysis/HistMemory.h"
9 
10 #include <daq/slc/base/IOException.h>
11 #include <daq/slc/base/StringUtil.h>
12 
13 #include <unistd.h>
14 #include <stdio.h>
15 #include <fcntl.h>
16 #include <sys/mman.h>
17 
18 using namespace Belle2;
19 
20 void HistMemory::open(const char* path, unsigned int size, const char* mode)
21 {
22  m_path = path;
23  m_size = size;
24  int flag = O_RDWR | O_CREAT | O_EXCL;
25  bool recreate = true;
26  if (mode != NULL && StringUtil::tolower(mode) == "recreate") {
27  flag = O_RDWR | O_CREAT;
28  }
29  int fd = ::open(m_path.c_str(), flag, 0666);
30  if (fd < 0) {
31  if (errno == EEXIST) {
32  recreate = false;
33  fd = ::open(m_path.c_str(), O_RDWR, 0666);
34  } else {
35  throw (IOException("Failed to open file %s : %s", path, strerror(errno)));
36  }
37  }
38  m_buf = new char[size];
39  ::memset(m_buf, 0, size);
40  if (recreate) {
41  int ret = ::write(fd, m_buf, size);
42  if (ret < 0) {
43  delete [] m_buf;
44  throw (IOException("Failed to clear file %s : %s", path, strerror(errno)));
45  }
46  }
47  m_fd = fd;
48  char* buf = (char*)mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, m_fd, 0);
49  m_mutex = MMutex(buf);
50  buf += m_mutex.size();
51  m_header = reinterpret_cast<Header*>(buf);
52  buf += sizeof(Header);
53  m_body = (char*)buf;
54  if (recreate) init();
55 }
56 
58 {
59  if (m_body == NULL) {
60  throw (IOException("%s is not opened", m_path.c_str()));
61  }
62  memset(m_buf, 0, m_size);
63  m_mutex.init();
64 }
65 
67 {
68  for (size_t i = 0; i < m_hist.size(); i++) {
69  m_handler.add(m_hist[i], m_hist[i]->GetName());
70  }
71  EvtMessage* msg = m_handler.encode_msg(MSG_EVENT);
72  (msg->header())->reserved[0] = 0;
73  (msg->header())->reserved[1] = (int)m_hist.size();
74  (msg->header())->reserved[2] = 0;
75  m_mutex.lock();
76  memcpy(m_body, (char*)msg->buffer(), msg->size());
77  m_header->nbytes = msg->size();
78  m_header->updateid++;
79  m_mutex.unlock();
80  delete msg;
81 }
82 
83 std::vector<TH1*>& HistMemory::deserialize(Header* header)
84 {
85  m_hist = std::vector<TH1*>();
86  m_mutex.lock();
87  if (m_header->updateid <= m_updateid) {
88  m_mutex.unlock();
89  return m_hist;
90  }
91  if (header != NULL) {
92  memcpy(header, m_header, sizeof(Header));
93  }
95  memcpy(m_buf, m_body, m_header->nbytes);
96  m_mutex.unlock();
97 
98  for (size_t i = 0; i < m_hist.size(); i++) {
99  delete m_hist[i];
100  }
101 
102  EvtMessage* msg = new EvtMessage(m_buf);
103  std::vector<TObject*> objlist;
104  std::vector<std::string> strlist;
105  m_handler.decode_msg(msg, objlist, strlist);
106  int nobjs = (msg->header())->reserved[1];
107  for (int i = 0; i < nobjs; i++) {
108  add((TH1*)objlist[i]->Clone());
109  }
110  delete msg;
111  return m_hist;
112 }
113 
Class to manage streamed object.
Definition: EvtMessage.h:59
EvtHeader * header()
Get pointer to EvtHeader.
Definition: EvtMessage.cc:161
char * buffer()
Get buffer address.
Definition: EvtMessage.cc:76
int size() const
Get size of message including headers.
Definition: EvtMessage.cc:94
void init()
Initialize the shared memory.
Definition: HistMemory.cc:57
TH1 * add(TH1 *h)
Add histogram to the list of histograms.
Definition: HistMemory.h:83
char * m_body
The pointer to the body of the message.
Definition: HistMemory.h:100
Header * m_header
The header for the message.
Definition: HistMemory.h:110
char * m_buf
The buffer to hold the message.
Definition: HistMemory.h:102
MsgHandler m_handler
The message handler.
Definition: HistMemory.h:96
std::string m_path
The name of the shared memory.
Definition: HistMemory.h:92
unsigned int m_updateid
The id of the udpate.
Definition: HistMemory.h:104
std::vector< TH1 * > m_hist
The list of the histograms.
Definition: HistMemory.h:112
std::vector< TH1 * > & deserialize(Header *header=NULL)
Deserialize the shared memory.
Definition: HistMemory.cc:83
void open(const char *path, unsigned int size, const char *mode="")
Open shared memory.
Definition: HistMemory.cc:20
int m_fd
The file descriptor.
Definition: HistMemory.h:98
MMutex m_mutex
The mutex lock for the shared memory.
Definition: HistMemory.h:108
unsigned int m_size
The size of the shared memory.
Definition: HistMemory.h:94
void serialize()
Serialize the shared memory.
Definition: HistMemory.cc:66
virtual void decode_msg(EvtMessage *msg, std::vector< TObject * > &objlist, std::vector< std::string > &namelist)
Decode an EvtMessage into a vector list of objects with names.
Definition: MsgHandler.cc:106
virtual void add(const TObject *, const std::string &name)
Add an object to be streamed.
Definition: MsgHandler.cc:46
virtual EvtMessage * encode_msg(ERecordType rectype)
Stream object list into an EvtMessage.
Definition: MsgHandler.cc:67
Abstract base class for different kinds of events.
Header information to deseriale the shared memory.
Definition: HistMemory.h:35
unsigned int nbytes
Number of bytes.
Definition: HistMemory.h:37
unsigned int updateid
Id of the update.
Definition: HistMemory.h:39