$treeview $search $mathjax $extrastylesheet
artdaq_core
v3_05_08a
$projectbrief
|
$projectbrief
|
$searchbox |
00001 00002 #define TRACE_NAME "SharedMemoryFragmentManager" 00003 #include "artdaq-core/Core/SharedMemoryFragmentManager.hh" 00004 #include "tracemf.h" 00005 00006 artdaq::SharedMemoryFragmentManager::SharedMemoryFragmentManager(uint32_t shm_key, size_t buffer_count, size_t max_buffer_size, size_t buffer_timeout_us) 00007 : SharedMemoryManager(shm_key, buffer_count, max_buffer_size, buffer_timeout_us) 00008 , active_buffer_(-1) 00009 { 00010 } 00011 00012 bool artdaq::SharedMemoryFragmentManager::ReadyForWrite(bool overwrite) 00013 { 00014 TLOG(12) << "ReadyForWrite: active_buffer is " << active_buffer_; 00015 if (active_buffer_ != -1) return true; 00016 active_buffer_ = GetBufferForWriting(overwrite); 00017 00018 return active_buffer_ != -1; 00019 } 00020 00021 int artdaq::SharedMemoryFragmentManager::WriteFragment(Fragment&& fragment, bool overwrite, size_t timeout_us) 00022 { 00023 if (!IsValid() || IsEndOfData()) 00024 { 00025 TLOG(TLVL_WARNING) << "WriteFragment: Shared memory is not connected! Attempting reconnect..."; 00026 auto sts = Attach(timeout_us); 00027 if (!sts) 00028 { 00029 return -1; 00030 } 00031 TLOG(TLVL_INFO) << "WriteFragment: Shared memory was successfully reconnected"; 00032 } 00033 00034 auto waitStart = std::chrono::steady_clock::now(); 00035 while (!ReadyForWrite(overwrite) && TimeUtils::GetElapsedTimeMicroseconds(waitStart) < 1000) 00036 { 00037 // BURN THAT CPU! 00038 } 00039 if (!ReadyForWrite(overwrite)) 00040 { 00041 int64_t loopCount = 0; 00042 size_t sleepTime = 1000; // microseconds 00043 int64_t nloops = (timeout_us - 1000) / sleepTime; 00044 00045 while (!ReadyForWrite(overwrite) && (!overwrite || timeout_us == 0 || loopCount < nloops)) 00046 { 00047 usleep(sleepTime); 00048 ++loopCount; 00049 } 00050 } 00051 if (!ReadyForWrite(overwrite)) 00052 { 00053 TLOG(TLVL_WARNING) << "No available buffers after waiting for " << TimeUtils::GetElapsedTimeMicroseconds(waitStart) << " us."; 00054 return -3; 00055 } 00056 00057 TLOG(13) << "Sending fragment with seqID=" << fragment.sequenceID() << " using buffer " << active_buffer_; 00058 artdaq::RawDataType* fragAddr = fragment.headerAddress(); 00059 size_t fragSize = fragment.size() * sizeof(artdaq::RawDataType); 00060 00061 auto sts = Write(active_buffer_, fragAddr, fragSize); 00062 if (sts == fragSize) 00063 { 00064 TLOG(13) << "Done sending Fragment with seqID=" << fragment.sequenceID() << " using buffer " << active_buffer_; 00065 MarkBufferFull(active_buffer_); 00066 active_buffer_ = -1; 00067 return 0; 00068 } 00069 active_buffer_ = -1; 00070 TLOG(TLVL_ERROR) << "Unexpected status from SharedMemory Write call!"; 00071 return -2; 00072 } 00073 00074 // NOT currently (2018-07-22) used! ReadFragmentHeader and ReadFragmentData 00075 // (below) are called directly 00076 int artdaq::SharedMemoryFragmentManager::ReadFragment(Fragment& fragment) 00077 { 00078 TLOG(14) << "ReadFragment BEGIN"; 00079 detail::RawFragmentHeader tmpHdr; 00080 00081 TLOG(14) << "Reading Fragment Header"; 00082 auto sts = ReadFragmentHeader(tmpHdr); 00083 if (sts != 0) return sts; 00084 fragment.resize(tmpHdr.word_count - tmpHdr.num_words()); 00085 memcpy(fragment.headerAddress(), &tmpHdr, tmpHdr.num_words() * sizeof(artdaq::RawDataType)); 00086 TLOG(14) << "Reading Fragment Body - of frag w/ seqID=" << tmpHdr.sequence_id; 00087 return ReadFragmentData(fragment.headerAddress() + tmpHdr.num_words(), tmpHdr.word_count - tmpHdr.num_words()); 00088 } 00089 00090 int artdaq::SharedMemoryFragmentManager::ReadFragmentHeader(detail::RawFragmentHeader& header) 00091 { 00092 if (!IsValid()) 00093 { 00094 TLOG(22) << "ReadFragmentHeader: !IsValid(), returning -3"; 00095 return -3; 00096 } 00097 00098 size_t hdrSize = artdaq::detail::RawFragmentHeader::num_words() * sizeof(artdaq::RawDataType); 00099 active_buffer_ = GetBufferForReading(); 00100 00101 if (active_buffer_ == -1) 00102 { 00103 TLOG(22) << "ReadFragmentHeader: active_buffer==-1, returning -1"; 00104 return -1; 00105 } 00106 00107 auto sts = Read(active_buffer_, &header, hdrSize); 00108 if (!sts) 00109 { 00110 TLOG(TLVL_ERROR) << "ReadFragmentHeader: Buffer " << active_buffer_ << " returned bad status code from Read"; 00111 MarkBufferEmpty(active_buffer_); 00112 active_buffer_ = -1; 00113 return -2; 00114 } 00115 00116 TLOG(22) << "ReadFragmentHeader: read active_buffer_=" << active_buffer_ << " sequence_id=" << header.sequence_id; 00117 return 0; 00118 } 00119 00120 int artdaq::SharedMemoryFragmentManager::ReadFragmentData(RawDataType* destination, size_t words) 00121 { 00122 if (!IsValid() || active_buffer_ == -1 || !CheckBuffer(active_buffer_, BufferSemaphoreFlags::Reading)) 00123 { 00124 TLOG(TLVL_ERROR) << "ReadFragmentData: Buffer " << active_buffer_ << " failed status checks: IsValid()=" << std::boolalpha << IsValid() << ", CheckBuffer=" << CheckBuffer(active_buffer_, BufferSemaphoreFlags::Reading); 00125 return -3; 00126 } 00127 00128 auto sts = Read(active_buffer_, destination, words * sizeof(RawDataType)); 00129 if (!sts) 00130 { 00131 TLOG(TLVL_ERROR) << "ReadFragmentData: Buffer " << active_buffer_ << " returned bad status code from Read"; 00132 MarkBufferEmpty(active_buffer_); 00133 active_buffer_ = -1; 00134 return -2; 00135 } 00136 00137 MarkBufferEmpty(active_buffer_); 00138 active_buffer_ = -1; 00139 return 0; 00140 }