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