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 "tracemf.h"
00011 #include "SharedMemoryTestShims.hh"
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, 10, 0x1000, 0x10000);
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, 10, 0x1000);
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);
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);
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);
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, 10, 0x1000);
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
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
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
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
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
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, 10, 0x1000, 0x10000, false);
00209 artdaq::SharedMemoryManager man3(key, 10, 0x1000, 0x10000, false);
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);
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);
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);
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
00272 readbuf = man3.GetBufferForReading();
00273 BOOST_REQUIRE_EQUAL(readbuf, buf);
00274 BOOST_REQUIRE_EQUAL(man3.GetBuffersOwnedByManager().size(), 1);
00275 BOOST_REQUIRE_EQUAL(man.ReadyForRead(), false);
00276 BOOST_REQUIRE_EQUAL(man3.CheckBuffer(buf, artdaq::SharedMemoryManager::BufferSemaphoreFlags::Reading), true);
00277 BOOST_REQUIRE_EQUAL(man3.MoreDataInBuffer(readbuf), true);
00278 sts = man3.Read(readbuf, &byte, 1);
00279 BOOST_REQUIRE_EQUAL(sts, true);
00280 BOOST_REQUIRE_EQUAL(byte, 1);
00281 BOOST_REQUIRE_EQUAL(man3.MoreDataInBuffer(readbuf), true);
00282 sts = man3.Read(readbuf, &byte, 1);
00283 BOOST_REQUIRE_EQUAL(sts, true);
00284 BOOST_REQUIRE_EQUAL(byte, 2);
00285 man3.IncrementReadPos(readbuf, 0x10);
00286 BOOST_REQUIRE_EQUAL(man3.MoreDataInBuffer(readbuf), true);
00287 sts = man3.Read(readbuf, &byte, 1);
00288 BOOST_REQUIRE_EQUAL(sts, true);
00289 BOOST_REQUIRE_EQUAL(byte, 0x13);
00290 man3.ResetReadPos(readbuf);
00291 BOOST_REQUIRE_EQUAL(man3.MoreDataInBuffer(readbuf), true);
00292 sts = man3.Read(readbuf, &byte, 1);
00293 BOOST_REQUIRE_EQUAL(sts, true);
00294 BOOST_REQUIRE_EQUAL(byte, 1);
00295 man3.IncrementReadPos(readbuf, 0xFFF);
00296 BOOST_REQUIRE_EQUAL(man3.MoreDataInBuffer(readbuf), false);
00297 man3.MarkBufferEmpty(readbuf);
00298 BOOST_REQUIRE_EQUAL(man3.ReadyForRead(), false);
00299 BOOST_REQUIRE_EQUAL(man2.ReadyForRead(), false);
00300 BOOST_REQUIRE_EQUAL(man.ReadyForRead(), false);
00301
00302 BOOST_REQUIRE_EQUAL(man2.GetBuffersOwnedByManager().size(), 0);
00303 BOOST_REQUIRE_EQUAL(man.GetBuffersOwnedByManager().size(), 0);
00304 BOOST_REQUIRE_EQUAL(man.WriteReadyCount(false), 9);
00305 BOOST_REQUIRE_EQUAL(man.WriteReadyCount(true), 10);
00306 sleep(1);
00307 BOOST_REQUIRE_EQUAL(man.WriteReadyCount(false), 10);
00308 TLOG(TLVL_DEBUG) << "END TEST Broadcast" ;
00309 }
00310
00311 BOOST_AUTO_TEST_SUITE_END()