Belle II Software  release-08-01-10
EventBuffer.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 "daq/storage/EventBuffer.h"
9 
10 #include <cstdio>
11 #include <cstdlib>
12 #include <cstring>
13 
14 using namespace Belle2;
15 
16 unsigned int EventBuffer::size() throw()
17 {
18  return sizeof(int) * (m_nword);
19 }
20 
21 EventBuffer::EventBuffer(unsigned int nword)
22 {
23  m_nword = nword;
24  char* buf = (char*) malloc(size());
25  if (buf == NULL) {
26  return;
27  }
28  m_buf = (int*)buf;
29  memset(&m_header, 0, sizeof(Header));
30  for (unsigned long long i = 0; i < m_nword; i++) {
31  m_buf[i] = 0;
32  }
33 }
34 
35 void EventBuffer::clear()
36 {
37  if (m_buf == NULL) return;
38  memset(&m_header, 0, sizeof(Header));
39  for (unsigned long long i = 0; i < m_nword; i++) {
40  m_buf[i] = 0;
41  }
42 }
43 
44 EventBuffer::~EventBuffer()
45 {
46  free(m_buf);
47 }
48 
49 bool EventBuffer::isWritable(int nword) throw()
50 {
51  if (m_buf == NULL) return false;
52  bool writable = m_header.nword_in - m_header.nword_out < m_nword - (nword + 1);
53  return writable;
54 }
55 
56 bool EventBuffer::isReadable() throw()
57 {
58  if (m_buf == NULL) return false;
59  bool readable = m_header.nword_in - m_header.nword_out > 0;
60  return readable;
61 }
62 
63 unsigned int EventBuffer::write(const int* buf, unsigned int nword,
64  unsigned int serial)
65 {
66  if (m_buf == NULL) return 0;
67  if (nword == 0) return 0;
68  if (nword > m_nword) return -1;
69 
70  while (true) {
71  unsigned int i_w = m_header.nword_in % m_nword;
72  unsigned int i_r = m_header.nword_out % m_nword;
73  if ((serial == 0 || serial - 1 == m_header.count_in) &&
74  m_header.nword_in - m_header.nword_out < m_nword - (nword + 1)) {
75  if (i_w >= i_r) {
76  unsigned int count = m_nword - i_w;
77  if (nword + 1 < count) {
78  m_buf[i_w] = nword;
79  memcpy((m_buf + i_w + 1), buf, sizeof(int) * nword);
80  } else {
81  m_buf[i_w] = nword;
82  memcpy((m_buf + i_w + 1), buf, sizeof(int) * count);
83  if (nword >= count)
84  memcpy(m_buf, buf + count, sizeof(int) * (nword - count));
85  }
86  } else {
87  m_buf[i_w] = nword;
88  memcpy((m_buf + i_w + 1), buf, sizeof(int) * nword);
89  }
90  break;
91  }
92  }
93  m_header.nword_in += nword + 1;
94  unsigned int count = ++m_header.count_in;
95  return count;
96 }
97 
98 unsigned int EventBuffer::read(int* buf, EventBuffer::Header* hdr)
99 {
100  if (m_buf == NULL) return 0;
101  m_header.nreader++;
102  unsigned int nword = 0;
103  while (true) {
104  unsigned int i_w = m_header.nword_in % m_nword;
105  unsigned int i_r = m_header.nword_out % m_nword;
106  nword = m_buf[i_r];
107  if (nword > 0) {
108  if (m_header.nword_in - m_header.nword_out >= (nword + 1)) {
109  if (i_w > i_r) {
110  memcpy(buf, (m_buf + i_r + 1), sizeof(int) * nword);
111  break;
112  } else if (i_w < i_r) {
113  if (m_nword - i_r > nword) {
114  memcpy(buf, (m_buf + i_r + 1), sizeof(int) * nword);
115  break;
116  } else {
117  unsigned int count = m_nword - i_r;
118  memcpy(buf, (m_buf + i_r + 1), sizeof(int) * count);
119  if (nword > count) {
120  memcpy(buf + count, m_buf, sizeof(int) * (nword - count));
121  }
122  break;
123  }
124  }
125  }
126  }
127  }
128  m_header.nword_out += nword + 1;
129  unsigned int count = ++m_header.count_out;
130  m_header.nreader--;
131  if (hdr != NULL) {
132  memcpy(hdr, &m_header, sizeof(EventBuffer::Header));
133  }
134  return count;
135 }
Abstract base class for different kinds of events.