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