00001 #include "artdaq-core/Core/SharedMemoryFragmentManager.hh" 00002 #include "tracemf.h" 00003 00004 00005 artdaq::SharedMemoryFragmentManager::SharedMemoryFragmentManager(uint32_t shm_key, size_t buffer_count, size_t max_buffer_size, size_t buffer_timeout_us) 00006 : SharedMemoryManager(shm_key, buffer_count, max_buffer_size, buffer_timeout_us) 00007 , active_buffer_(-1) 00008 { 00009 00010 } 00011 00012 int artdaq::SharedMemoryFragmentManager::WriteFragment(Fragment&& fragment, bool overwrite) 00013 { 00014 if (!IsValid()) { return -1; } 00015 00016 TLOG_ARB(13, "SharedMemoryFragmentManager") << "Sending fragment with seqID=" << fragment.sequenceID() << TLOG_ENDL; 00017 artdaq::RawDataType* fragAddr = fragment.headerAddress(); 00018 size_t fragSize = fragment.size() * sizeof(artdaq::RawDataType); 00019 00020 auto buf = GetBufferForWriting(overwrite); 00021 auto sts = Write(buf, fragAddr, fragSize); 00022 if(sts == fragSize) 00023 { 00024 TLOG_ARB(13, "SharedMemoryFragmentManager") << "Done sending Fragment with seqID=" << fragment.sequenceID() << TLOG_ENDL; 00025 MarkBufferFull(buf); 00026 return 0; 00027 } 00028 TLOG_ERROR("SharedMemoryFragmentManager") << "Unexpected status from SharedMemory Write call!" << TLOG_ENDL; 00029 return -2; 00030 } 00031 00032 int artdaq::SharedMemoryFragmentManager::ReadFragment(Fragment& fragment) 00033 { 00034 TLOG_ARB(13, "SharedMemoryFragmentManager") << "ReadFragment BEGIN" << TLOG_ENDL; 00035 detail::RawFragmentHeader tmpHdr; 00036 00037 TLOG_ARB(13, "SharedMemoryFragmentManager") << "Reading Fragment Header" << TLOG_ENDL; 00038 auto sts = ReadFragmentHeader(tmpHdr); 00039 if (sts != 0) return sts; 00040 fragment.resize(tmpHdr.word_count - tmpHdr.num_words()); 00041 memcpy(fragment.headerAddress(), &tmpHdr, tmpHdr.num_words() * sizeof(artdaq::RawDataType)); 00042 TLOG_ARB(13, "SharedMemoryFragmentManager") << "Reading Fragment Body" << TLOG_ENDL; 00043 return ReadFragmentData(fragment.headerAddress() + tmpHdr.num_words(), tmpHdr.word_count - tmpHdr.num_words()); 00044 } 00045 00046 int artdaq::SharedMemoryFragmentManager::ReadFragmentHeader(detail::RawFragmentHeader& header) 00047 { 00048 if (!IsValid()) return -3; 00049 00050 size_t hdrSize = artdaq::detail::RawFragmentHeader::num_words() * sizeof(artdaq::RawDataType); 00051 active_buffer_ = GetBufferForReading(); 00052 00053 if (active_buffer_ == -1) return -1; 00054 00055 auto sts = Read(active_buffer_, &header, hdrSize); 00056 if (!sts) return -2; 00057 00058 return 0; 00059 } 00060 00061 int artdaq::SharedMemoryFragmentManager::ReadFragmentData(RawDataType* destination, size_t words) 00062 { 00063 if (!IsValid() || active_buffer_ == -1 || !CheckBuffer(active_buffer_, BufferSemaphoreFlags::Reading)) { 00064 TLOG_ERROR("SharedMemoryFragmentManager") << "ReadFragmentData: Buffer " << active_buffer_ << " failed status checks: IsValid()=" << std::boolalpha << IsValid() << ", CheckBuffer=" << CheckBuffer(active_buffer_, BufferSemaphoreFlags::Reading) << TLOG_ENDL; 00065 return -3; 00066 } 00067 00068 auto sts = Read(active_buffer_, destination, words * sizeof(RawDataType)); 00069 if (!sts) { 00070 TLOG_ERROR("SharedMemoryFragmentManager") << "ReadFragmentData: Buffer " << active_buffer_ << " returned bad status code from Read" << TLOG_ENDL; 00071 return -2; 00072 } 00073 00074 MarkBufferEmpty(active_buffer_); 00075 active_buffer_ = -1; 00076 return 0; 00077 }