Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-05-31 04:19:42

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