Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-05-18 03:27:20

0001 #include "FWCore/Utilities/interface/Exception.h"
0002 #include "IOPool/Streamer/interface/EventMsgBuilder.h"
0003 #include "IOPool/Streamer/interface/EventMessage.h"
0004 #include "IOPool/Streamer/interface/MsgHeader.h"
0005 #include <cassert>
0006 #include <cstring>
0007 
0008 #define MAX_HOSTNAME_LEN 25
0009 
0010 EventMsgBuilder::EventMsgBuilder(void* buf,
0011                                  uint32 size,
0012                                  uint32 run,
0013                                  uint64 event,
0014                                  uint32 lumi,
0015                                  uint32 outModId,
0016                                  uint32 droppedEventsCount,
0017                                  std::vector<bool>& l1_bits,
0018                                  uint8* hlt_bits,
0019                                  uint32 hlt_bit_count,
0020                                  uint32 adler_chksum,
0021                                  const char* host_name)
0022     : buf_((uint8*)buf), size_(size) {
0023   uint32 expectedHeaderSize = computeHeaderSize(l1_bits.size(), hlt_bit_count);
0024   if (expectedHeaderSize > size_) {
0025     throw cms::Exception("EventMsgBuilder")
0026         << "The buffer used to build the event message (" << size_
0027         << " bytes) is not large enough to holde the event header (" << expectedHeaderSize << " bytes)";
0028   }
0029 
0030   // Note: any change to the pos increment logic should be reflected in computeHeaderSize()
0031   uint8* pos = buf_;
0032 
0033   // Set the event header
0034   EventHeader* h = (EventHeader*)pos;
0035   h->protocolVersion_ = 11;
0036   convert(run, h->run_);
0037   convert(event, h->event_);
0038   convert(lumi, h->lumi_);
0039   convert(outModId, h->outModId_);
0040   convert(droppedEventsCount, h->droppedEventsCount_);
0041   pos += sizeof(EventHeader);
0042 
0043   // Set the L1T triggers count
0044   uint32 l1_count = l1_bits.size();
0045   convert(l1_count, pos);
0046   pos += sizeof(uint32);
0047 
0048   // Set the L1T bits
0049   uint32 l1_sz = (l1_bits.size() + 8 - 1) / 8;  // L1T results (1 bit per trigger)
0050   memset(pos, 0x00, l1_sz);                     // clear the bits
0051   for (std::vector<bool>::size_type i = 0; i < l1_bits.size(); ++i) {
0052     uint8 v = l1_bits[i] ? 1 : 0;
0053     pos[i / 8] |= (v << (i & 0x07));
0054   }
0055   pos += l1_sz;
0056 
0057   // Set HLT triggers count
0058   convert(hlt_bit_count, pos);
0059   pos += sizeof(uint32);
0060 
0061   // Copy the HLT bits and increment pos
0062   uint32 hlt_sz = (hlt_bit_count + 4 - 1) / 4;  // HLT results (2 bits per trigger)
0063   pos = std::copy(hlt_bits, hlt_bits + hlt_sz, pos);
0064 
0065   // Set the Adler32 check sum of data blob
0066   convert(adler_chksum, pos);
0067   pos += sizeof(uint32);
0068 
0069   // Put the host name (length and then name) right after the check sum.
0070   // Use a fixed length for the host_name because the event header size appears in the
0071   // init message and only one goes to a file whereas events can come from any node,
0072   // while we want the max length to be determined inside this Event Message Builder.
0073 
0074   // Set the host_name_len and increment pos
0075   assert(MAX_HOSTNAME_LEN < 0x00ff);
0076   *pos++ = MAX_HOSTNAME_LEN;
0077 
0078   // Copy up to MAX_HOSTNAME_LEN characters of the host_name and pad any extra space
0079   // with null characters
0080   memset(pos, '\0', MAX_HOSTNAME_LEN);
0081   strncpy((char*)pos, host_name, MAX_HOSTNAME_LEN - 1);
0082   pos += MAX_HOSTNAME_LEN;
0083 
0084   event_addr_ = pos + sizeof(char_uint32);
0085   setEventLength(0);
0086 
0087   // Check that the size computed by computeHeaderSize() matches what is actually used.
0088   if (headerSize() != expectedHeaderSize) {
0089     throw cms::Exception("EventMsgBuilder")
0090         << "The event message header size (" << headerSize() << " bytes) does not match the computed value ("
0091         << expectedHeaderSize << " bytes)";
0092   }
0093 }
0094 
0095 void EventMsgBuilder::setOrigDataSize(uint32 value) {
0096   EventHeader* h = (EventHeader*)buf_;
0097   convert(value, h->origDataSize_);
0098 }
0099 
0100 void EventMsgBuilder::setEventLength(uint32 len) {
0101   convert(len, event_addr_ - sizeof(char_uint32));
0102   EventHeader* h = (EventHeader*)buf_;
0103   new (&h->header_) Header(Header::EVENT, event_addr_ - buf_ + len);
0104 }
0105 
0106 uint32 EventMsgBuilder::size() const {
0107   HeaderView v(buf_);
0108   return v.size();
0109 }
0110 
0111 uint32 EventMsgBuilder::computeHeaderSize(uint32 l1t_bit_count, uint32 hlt_bit_count) {
0112   uint32 size = sizeof(EventHeader);    // event header
0113   size += sizeof(uint32);               // L1T triggers count
0114   size += (l1t_bit_count + 8 - 1) / 8;  // L1T results (1 bit per trigger)
0115   size += sizeof(uint32);               // HLT triggers count
0116   size += (hlt_bit_count + 4 - 1) / 4;  // HLT results (2 bits per trigger)
0117   size += sizeof(uint32);               // adler32 check sum
0118   size += 1;                            // host name length
0119   size += MAX_HOSTNAME_LEN;             // host name
0120   size += sizeof(char_uint32);          // event address
0121   return size;
0122 }