$treeview $search $mathjax $extrastylesheet
artdaq_core
v3_06_01
$projectbrief
|
$projectbrief
|
$searchbox |
00001 #include "artdaq-core/Core/SharedMemoryManager.hh" 00002 #include "artdaq-core/Utilities/TimeUtils.hh" 00003 #include "artdaq-core/Utilities/configureMessageFacility.hh" 00004 00005 #define BOOST_TEST_MODULE SharedMemoryManager_t 00006 #include "cetlib/quiet_unit_test.hpp" 00007 #include "cetlib_except/exception.h" 00008 00009 #define TRACE_NAME "SharedMemoryManager_t" 00010 #include "SharedMemoryTestShims.hh" 00011 #include "tracemf.h" 00012 00013 BOOST_AUTO_TEST_SUITE(SharedMemoryManager_test) 00014 00015 BOOST_AUTO_TEST_CASE(Construct) 00016 { 00017 artdaq::configureMessageFacility("SharedMemoryManager_t", true, true); 00018 TLOG(TLVL_DEBUG) << "BEGIN TEST Construct"; 00019 uint32_t key = GetRandomKey(0x7357); 00020 artdaq::SharedMemoryManager man(key, 10, 0x1000, 0x10000); 00021 BOOST_REQUIRE_EQUAL(man.IsValid(), true); 00022 BOOST_REQUIRE_EQUAL(man.GetMyId(), 0); 00023 BOOST_REQUIRE_EQUAL(man.size(), 10); 00024 BOOST_REQUIRE_EQUAL(man.GetAttachedCount(), 1); 00025 BOOST_REQUIRE_EQUAL(man.GetKey(), key); 00026 TLOG(TLVL_DEBUG) << "END TEST Construct"; 00027 } 00028 00029 BOOST_AUTO_TEST_CASE(Attach) 00030 { 00031 TLOG(TLVL_DEBUG) << "BEGIN TEST Attach"; 00032 uint32_t key = GetRandomKey(0x7357); 00033 artdaq::SharedMemoryManager man(key, 10, 0x1000, 0x10000); 00034 artdaq::SharedMemoryManager man2(key); 00035 00036 BOOST_REQUIRE_EQUAL(man.IsValid(), true); 00037 BOOST_REQUIRE_EQUAL(man.GetMyId(), 0); 00038 BOOST_REQUIRE_EQUAL(man.size(), 10); 00039 BOOST_REQUIRE_EQUAL(man.GetAttachedCount(), 2); 00040 BOOST_REQUIRE_EQUAL(man.GetKey(), key); 00041 00042 BOOST_REQUIRE_EQUAL(man2.IsValid(), true); 00043 BOOST_REQUIRE_EQUAL(man2.GetMyId(), 1); 00044 BOOST_REQUIRE_EQUAL(man2.size(), 10); 00045 BOOST_REQUIRE_EQUAL(man2.GetAttachedCount(), 2); 00046 BOOST_REQUIRE_EQUAL(man2.GetKey(), key); 00047 00048 TLOG(TLVL_DEBUG) << "END TEST Attach"; 00049 } 00050 00051 BOOST_AUTO_TEST_CASE(DataFlow) 00052 { 00053 TLOG(TLVL_DEBUG) << "BEGIN TEST DataFlow"; 00054 uint32_t key = GetRandomKey(0x7357); 00055 artdaq::SharedMemoryManager man(key, 10, 0x1000); 00056 artdaq::SharedMemoryManager man2(key); 00057 00058 BOOST_REQUIRE_EQUAL(man.ReadyForWrite(false), true); 00059 BOOST_REQUIRE_EQUAL(man.WriteReadyCount(false), 10); 00060 BOOST_REQUIRE_EQUAL(man.ReadyForRead(), false); 00061 BOOST_REQUIRE_EQUAL(man.ReadReadyCount(), 0); 00062 00063 int buf = man.GetBufferForWriting(false); 00064 BOOST_REQUIRE_EQUAL(man.CheckBuffer(buf, artdaq::SharedMemoryManager::BufferSemaphoreFlags::Writing), true); 00065 BOOST_REQUIRE_EQUAL(man.GetBuffersOwnedByManager().size(), 1); 00066 BOOST_REQUIRE_EQUAL(man.GetBuffersOwnedByManager()[0], buf); 00067 BOOST_REQUIRE_EQUAL(man2.GetBuffersOwnedByManager().size(), 0); 00068 BOOST_REQUIRE_EQUAL(man.BufferDataSize(buf), 0); 00069 00070 uint8_t n = 0; 00071 uint8_t data[0x1000]; 00072 std::generate_n(data, 0x1000, [&]() { return ++n; }); 00073 man.Write(buf, data, 0x1000); 00074 BOOST_REQUIRE_EQUAL(man.BufferDataSize(buf), 0x1000); 00075 BOOST_REQUIRE_EQUAL(man2.BufferDataSize(buf), 0x1000); 00076 man.MarkBufferFull(buf, 1); 00077 BOOST_REQUIRE_EQUAL(man2.CheckBuffer(buf, artdaq::SharedMemoryManager::BufferSemaphoreFlags::Full), true); 00078 BOOST_REQUIRE_EQUAL(man.GetBuffersOwnedByManager().size(), 0); 00079 BOOST_REQUIRE_EQUAL(man2.GetBuffersOwnedByManager().size(), 1); 00080 00081 BOOST_REQUIRE_EQUAL(man.ReadyForRead(), false); 00082 BOOST_REQUIRE_EQUAL(man2.ReadyForRead(), true); 00083 BOOST_REQUIRE_EQUAL(man2.ReadReadyCount(), 1); 00084 00085 auto readbuf = man2.GetBufferForReading(); 00086 BOOST_REQUIRE_EQUAL(man2.CheckBuffer(buf, artdaq::SharedMemoryManager::BufferSemaphoreFlags::Reading), true); 00087 BOOST_REQUIRE_EQUAL(man2.MoreDataInBuffer(readbuf), true); 00088 uint8_t byte; 00089 auto sts = man2.Read(readbuf, &byte, 1); 00090 BOOST_REQUIRE_EQUAL(sts, true); 00091 BOOST_REQUIRE_EQUAL(byte, 1); // ++n means that the first entry will be 1 00092 BOOST_REQUIRE_EQUAL(man2.MoreDataInBuffer(readbuf), true); 00093 sts = man2.Read(readbuf, &byte, 1); 00094 BOOST_REQUIRE_EQUAL(sts, true); 00095 BOOST_REQUIRE_EQUAL(byte, 2); // Second entry is 2 00096 man2.IncrementReadPos(readbuf, 0x10); 00097 BOOST_REQUIRE_EQUAL(man2.MoreDataInBuffer(readbuf), true); 00098 sts = man2.Read(readbuf, &byte, 1); 00099 BOOST_REQUIRE_EQUAL(sts, true); 00100 BOOST_REQUIRE_EQUAL(byte, 0x13); // Read increments, so it would have read 3, but we added 0x10, so we expect 0x13. 00101 man2.ResetReadPos(readbuf); 00102 BOOST_REQUIRE_EQUAL(man2.MoreDataInBuffer(readbuf), true); 00103 sts = man2.Read(readbuf, &byte, 1); 00104 BOOST_REQUIRE_EQUAL(sts, true); 00105 BOOST_REQUIRE_EQUAL(byte, 1); 00106 man2.IncrementReadPos(readbuf, 0xFFF); 00107 BOOST_REQUIRE_EQUAL(man2.MoreDataInBuffer(readbuf), false); 00108 man2.MarkBufferEmpty(readbuf); 00109 00110 BOOST_REQUIRE_EQUAL(man2.GetBuffersOwnedByManager().size(), 0); 00111 BOOST_REQUIRE_EQUAL(man.GetBuffersOwnedByManager().size(), 0); 00112 BOOST_REQUIRE_EQUAL(man.WriteReadyCount(false), 10); 00113 TLOG(TLVL_DEBUG) << "END TEST DataFlow"; 00114 } 00115 00116 BOOST_AUTO_TEST_CASE(Exceptions) 00117 { 00118 artdaq::configureMessageFacility("SharedMemoryManager_t", true, true); 00119 TLOG(TLVL_DEBUG) << "BEGIN TEST Exceptions"; 00120 uint32_t key = GetRandomKey(0x7357); 00121 artdaq::SharedMemoryManager man(key, 10, 0x1000); 00122 artdaq::SharedMemoryManager man2(key); 00123 BOOST_REQUIRE_EQUAL(man.ReadyForWrite(false), true); 00124 BOOST_REQUIRE_EQUAL(man.WriteReadyCount(false), 10); 00125 BOOST_REQUIRE_EQUAL(man.ReadyForRead(), false); 00126 BOOST_REQUIRE_EQUAL(man.ReadReadyCount(), 0); 00127 00128 // Trying to get an invalid buffer is an exception 00129 BOOST_REQUIRE_EXCEPTION(man.ResetReadPos(11), cet::exception, [&](cet::exception e) { return e.category() == "ArgumentOutOfRange"; }); 00130 BOOST_REQUIRE_EQUAL(man.IsValid(), false); 00131 00132 man.Attach(); 00133 // Trying to access a buffer that is in the wrong state is an exception 00134 BOOST_REQUIRE_EXCEPTION(man.MarkBufferEmpty(0), cet::exception, [&](cet::exception e) { return e.category() == "StateAccessViolation"; }); 00135 BOOST_REQUIRE_EQUAL(man.IsValid(), false); 00136 00137 man.Attach(); 00138 00139 // Writing too much data is an exception 00140 int buf = man.GetBufferForWriting(false); 00141 BOOST_REQUIRE_EQUAL(man.CheckBuffer(buf, artdaq::SharedMemoryManager::BufferSemaphoreFlags::Writing), true); 00142 BOOST_REQUIRE_EQUAL(man.GetBuffersOwnedByManager().size(), 1); 00143 BOOST_REQUIRE_EQUAL(man.GetBuffersOwnedByManager()[0], buf); 00144 BOOST_REQUIRE_EQUAL(man.BufferDataSize(buf), 0); 00145 00146 uint8_t n = 0; 00147 uint8_t data[0x2000]; 00148 std::generate_n(data, 0x2000, [&]() { return ++n; }); 00149 BOOST_REQUIRE_EXCEPTION(man.Write(buf, data, 0x2000), cet::exception, [&](cet::exception e) { return e.category() == "SharedMemoryWrite"; }); 00150 BOOST_REQUIRE_EQUAL(man.IsValid(), false); 00151 00152 man.Attach(); 00153 man2.Attach(); 00154 buf = man.GetBufferForWriting(false); 00155 BOOST_REQUIRE_EQUAL(man.CheckBuffer(buf, artdaq::SharedMemoryManager::BufferSemaphoreFlags::Writing), true); 00156 BOOST_REQUIRE_EQUAL(man.GetBuffersOwnedByManager().size(), 1); 00157 BOOST_REQUIRE_EQUAL(man.GetBuffersOwnedByManager()[0], buf); 00158 BOOST_REQUIRE_EQUAL(man.BufferDataSize(buf), 0); 00159 man.Write(buf, data, 0x1000); 00160 man.MarkBufferFull(buf); 00161 00162 // Reading too much data is an exception 00163 BOOST_REQUIRE_EQUAL(man2.IsValid(), true); 00164 BOOST_REQUIRE_EQUAL(man2.ReadyForRead(), true); 00165 BOOST_REQUIRE_EQUAL(man2.ReadReadyCount(), 1); 00166 00167 int readbuf = man2.GetBufferForReading(); 00168 BOOST_REQUIRE_EQUAL(readbuf, buf); 00169 BOOST_REQUIRE_EXCEPTION(man2.Read(readbuf, data, 0x1001), cet::exception, [&](cet::exception e) { return e.category() == "SharedMemoryRead"; }); 00170 BOOST_REQUIRE_EQUAL(man2.IsValid(), false); 00171 00172 man.Attach(); 00173 man2.Attach(); 00174 00175 man.MarkBufferEmpty(readbuf, true); 00176 buf = man.GetBufferForWriting(false); 00177 BOOST_REQUIRE_EQUAL(man.CheckBuffer(buf, artdaq::SharedMemoryManager::BufferSemaphoreFlags::Writing), true); 00178 BOOST_REQUIRE_EQUAL(man.GetBuffersOwnedByManager().size(), 1); 00179 BOOST_REQUIRE_EQUAL(man.GetBuffersOwnedByManager()[0], buf); 00180 BOOST_REQUIRE_EQUAL(man.BufferDataSize(buf), 0); 00181 man.Write(buf, data, 0x1000); 00182 BOOST_REQUIRE_EQUAL(man.GetBuffersOwnedByManager().size(), 1); 00183 BOOST_REQUIRE_EQUAL(man.GetBuffersOwnedByManager()[0], buf); 00184 BOOST_REQUIRE_EQUAL(man.BufferDataSize(buf), 0x1000); 00185 man.MarkBufferFull(buf); 00186 BOOST_REQUIRE_EQUAL(man.GetBuffersOwnedByManager().size(), 0); 00187 BOOST_REQUIRE_EQUAL(man.BufferDataSize(buf), 0x1000); 00188 00189 BOOST_REQUIRE_EQUAL(man2.ReadyForRead(), true); 00190 BOOST_REQUIRE_EQUAL(man2.ReadReadyCount(), 1); 00191 readbuf = man2.GetBufferForReading(); 00192 BOOST_REQUIRE_EQUAL(readbuf, buf); 00193 BOOST_REQUIRE_EQUAL(man2.GetBuffersOwnedByManager().size(), 1); 00194 BOOST_REQUIRE_EQUAL(man2.GetBuffersOwnedByManager()[0], readbuf); 00195 BOOST_REQUIRE_EQUAL(man2.BufferDataSize(readbuf), 0x1000); 00196 // Accessing a buffer that is not owned by the manager is an exception 00197 BOOST_REQUIRE_EXCEPTION(man.MarkBufferEmpty(readbuf), cet::exception, [&](cet::exception e) { return e.category() == "OwnerAccessViolation"; }); 00198 BOOST_REQUIRE_EQUAL(man.IsValid(), false); 00199 00200 TLOG(TLVL_DEBUG) << "END TEST Exceptions"; 00201 } 00202 00203 BOOST_AUTO_TEST_CASE(Broadcast) 00204 { 00205 TLOG(TLVL_DEBUG) << "BEGIN TEST Broadcast"; 00206 uint32_t key = GetRandomKey(0x7357); 00207 artdaq::SharedMemoryManager man(key, 10, 0x1000, 0x10000, false); 00208 artdaq::SharedMemoryManager man2(key); 00209 artdaq::SharedMemoryManager man3(key); 00210 00211 BOOST_REQUIRE_EQUAL(man.ReadyForWrite(false), true); 00212 BOOST_REQUIRE_EQUAL(man.WriteReadyCount(false), 10); 00213 BOOST_REQUIRE_EQUAL(man.ReadyForRead(), false); 00214 BOOST_REQUIRE_EQUAL(man.ReadReadyCount(), 0); 00215 00216 int buf = man.GetBufferForWriting(false); 00217 BOOST_REQUIRE_EQUAL(man.CheckBuffer(buf, artdaq::SharedMemoryManager::BufferSemaphoreFlags::Writing), true); 00218 BOOST_REQUIRE_EQUAL(man.GetBuffersOwnedByManager().size(), 1); 00219 BOOST_REQUIRE_EQUAL(man.GetBuffersOwnedByManager()[0], buf); 00220 BOOST_REQUIRE_EQUAL(man2.GetBuffersOwnedByManager().size(), 0); 00221 BOOST_REQUIRE_EQUAL(man.BufferDataSize(buf), 0); 00222 00223 uint8_t n = 0; 00224 uint8_t data[0x1000]; 00225 std::generate_n(data, 0x1000, [&]() { return ++n; }); 00226 man.Write(buf, data, 0x1000); 00227 BOOST_REQUIRE_EQUAL(man.BufferDataSize(buf), 0x1000); 00228 BOOST_REQUIRE_EQUAL(man2.BufferDataSize(buf), 0x1000); 00229 man.MarkBufferFull(buf, -1); 00230 BOOST_REQUIRE_EQUAL(man2.CheckBuffer(buf, artdaq::SharedMemoryManager::BufferSemaphoreFlags::Full), true); 00231 BOOST_REQUIRE_EQUAL(man.GetBuffersOwnedByManager().size(), 0); 00232 00233 BOOST_REQUIRE_EQUAL(man.ReadyForRead(), false); 00234 BOOST_REQUIRE_EQUAL(man2.ReadyForRead(), true); 00235 BOOST_REQUIRE_EQUAL(man2.ReadReadyCount(), 1); 00236 00237 auto readbuf = man2.GetBufferForReading(); 00238 BOOST_REQUIRE_EQUAL(readbuf, buf); 00239 BOOST_REQUIRE_EQUAL(man2.GetBuffersOwnedByManager().size(), 1); 00240 BOOST_REQUIRE_EQUAL(man.ReadyForRead(), false); 00241 BOOST_REQUIRE_EQUAL(man3.ReadyForRead(), false); 00242 BOOST_REQUIRE_EQUAL(man2.CheckBuffer(buf, artdaq::SharedMemoryManager::BufferSemaphoreFlags::Reading), true); 00243 BOOST_REQUIRE_EQUAL(man2.MoreDataInBuffer(readbuf), true); 00244 uint8_t byte; 00245 auto sts = man2.Read(readbuf, &byte, 1); 00246 BOOST_REQUIRE_EQUAL(sts, true); 00247 BOOST_REQUIRE_EQUAL(byte, 1); // ++n means that the first entry will be 1 00248 BOOST_REQUIRE_EQUAL(man2.MoreDataInBuffer(readbuf), true); 00249 sts = man2.Read(readbuf, &byte, 1); 00250 BOOST_REQUIRE_EQUAL(sts, true); 00251 BOOST_REQUIRE_EQUAL(byte, 2); // Second entry is 2 00252 man2.IncrementReadPos(readbuf, 0x10); 00253 BOOST_REQUIRE_EQUAL(man2.MoreDataInBuffer(readbuf), true); 00254 sts = man2.Read(readbuf, &byte, 1); 00255 BOOST_REQUIRE_EQUAL(sts, true); 00256 BOOST_REQUIRE_EQUAL(byte, 0x13); // Read increments, so it would have read 3, but we added 0x10, so we expect 0x13. 00257 man2.ResetReadPos(readbuf); 00258 BOOST_REQUIRE_EQUAL(man2.MoreDataInBuffer(readbuf), true); 00259 sts = man2.Read(readbuf, &byte, 1); 00260 BOOST_REQUIRE_EQUAL(sts, true); 00261 BOOST_REQUIRE_EQUAL(byte, 1); 00262 man2.IncrementReadPos(readbuf, 0xFFF); 00263 BOOST_REQUIRE_EQUAL(man2.MoreDataInBuffer(readbuf), false); 00264 man2.MarkBufferEmpty(readbuf); 00265 BOOST_REQUIRE_EQUAL(man3.ReadyForRead(), true); 00266 BOOST_REQUIRE_EQUAL(man3.ReadReadyCount(), 1); 00267 BOOST_REQUIRE_EQUAL(man2.ReadyForRead(), false); 00268 BOOST_REQUIRE_EQUAL(man2.ReadReadyCount(), 0); 00269 BOOST_REQUIRE_EQUAL(man.ReadyForRead(), false); 00270 00271 readbuf = man3.GetBufferForReading(); 00272 BOOST_REQUIRE_EQUAL(readbuf, buf); 00273 BOOST_REQUIRE_EQUAL(man3.GetBuffersOwnedByManager().size(), 1); 00274 BOOST_REQUIRE_EQUAL(man.ReadyForRead(), false); 00275 BOOST_REQUIRE_EQUAL(man3.CheckBuffer(buf, artdaq::SharedMemoryManager::BufferSemaphoreFlags::Reading), true); 00276 BOOST_REQUIRE_EQUAL(man3.MoreDataInBuffer(readbuf), true); 00277 sts = man3.Read(readbuf, &byte, 1); 00278 BOOST_REQUIRE_EQUAL(sts, true); 00279 BOOST_REQUIRE_EQUAL(byte, 1); // ++n means that the first entry will be 1 00280 BOOST_REQUIRE_EQUAL(man3.MoreDataInBuffer(readbuf), true); 00281 sts = man3.Read(readbuf, &byte, 1); 00282 BOOST_REQUIRE_EQUAL(sts, true); 00283 BOOST_REQUIRE_EQUAL(byte, 2); // Second entry is 2 00284 man3.IncrementReadPos(readbuf, 0x10); 00285 BOOST_REQUIRE_EQUAL(man3.MoreDataInBuffer(readbuf), true); 00286 sts = man3.Read(readbuf, &byte, 1); 00287 BOOST_REQUIRE_EQUAL(sts, true); 00288 BOOST_REQUIRE_EQUAL(byte, 0x13); // Read increments, so it would have read 3, but we added 0x10, so we expect 0x13. 00289 man3.ResetReadPos(readbuf); 00290 BOOST_REQUIRE_EQUAL(man3.MoreDataInBuffer(readbuf), true); 00291 sts = man3.Read(readbuf, &byte, 1); 00292 BOOST_REQUIRE_EQUAL(sts, true); 00293 BOOST_REQUIRE_EQUAL(byte, 1); 00294 man3.IncrementReadPos(readbuf, 0xFFF); 00295 BOOST_REQUIRE_EQUAL(man3.MoreDataInBuffer(readbuf), false); 00296 man3.MarkBufferEmpty(readbuf); 00297 BOOST_REQUIRE_EQUAL(man3.ReadyForRead(), false); 00298 BOOST_REQUIRE_EQUAL(man2.ReadyForRead(), false); 00299 BOOST_REQUIRE_EQUAL(man.ReadyForRead(), false); 00300 00301 BOOST_REQUIRE_EQUAL(man2.GetBuffersOwnedByManager().size(), 0); 00302 BOOST_REQUIRE_EQUAL(man.GetBuffersOwnedByManager().size(), 0); 00303 BOOST_REQUIRE_EQUAL(man.WriteReadyCount(false), 9); 00304 BOOST_REQUIRE_EQUAL(man.WriteReadyCount(true), 10); 00305 sleep(1); 00306 BOOST_REQUIRE_EQUAL(man.WriteReadyCount(false), 10); 00307 TLOG(TLVL_DEBUG) << "END TEST Broadcast"; 00308 } 00309 00310 BOOST_AUTO_TEST_SUITE_END()