File indexing completed on 2021-12-22 01:53:32
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include "DataFormats/Provenance/interface/EventID.h"
0015 #include "FWCore/Framework/interface/DataKey.h"
0016 #include "FWCore/Framework/interface/ESSourceDataProxyNonConcurrentBase.h"
0017 #include "FWCore/Framework/interface/DataProxyProvider.h"
0018 #include "FWCore/Framework/interface/EventSetupRecordIntervalFinder.h"
0019 #include "FWCore/Framework/interface/EventSetupRecordKey.h"
0020 #include "FWCore/Framework/interface/IOVSyncValue.h"
0021 #include "FWCore/Framework/interface/SourceFactory.h"
0022 #include "FWCore/Framework/interface/ValidityInterval.h"
0023 #include "FWCore/Integration/interface/ESTestRecords.h"
0024 #include "FWCore/Integration/test/IOVTestInfo.h"
0025 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0026 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0027 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0028 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0029 #include "FWCore/Utilities/interface/Exception.h"
0030
0031 #include <atomic>
0032 #include <cmath>
0033 #include <limits>
0034 #include <set>
0035 #include <utility>
0036 #include <vector>
0037 #include <mutex>
0038
0039 namespace edmtest {
0040
0041 class TestESSource;
0042
0043 class TestESSourceTestProxy : public edm::eventsetup::ESSourceDataProxyNonConcurrentBase {
0044 public:
0045 TestESSourceTestProxy(TestESSource* testESSource);
0046
0047 private:
0048 void prefetch(edm::eventsetup::DataKey const&, edm::EventSetupRecordDetails) override;
0049 void initializeForNewIOV() override;
0050 void const* getAfterPrefetchImpl() const override;
0051
0052 IOVTestInfo iovTestInfo_;
0053 TestESSource* testESSource_;
0054 };
0055
0056 class TestESSource : public edm::eventsetup::DataProxyProvider, public edm::EventSetupRecordIntervalFinder {
0057 public:
0058 using EventSetupRecordKey = edm::eventsetup::EventSetupRecordKey;
0059 explicit TestESSource(edm::ParameterSet const&);
0060 ~TestESSource();
0061
0062 static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0063
0064 void busyWait(char const* msg) const;
0065
0066 std::atomic<unsigned int> count_;
0067 std::atomic<unsigned int> count1_;
0068 std::atomic<unsigned int> count2_;
0069 edm::SerialTaskQueue queue_;
0070 std::mutex mutex_;
0071
0072 private:
0073 bool isConcurrentFinder() const override { return true; }
0074 void setIntervalFor(EventSetupRecordKey const&, edm::IOVSyncValue const&, edm::ValidityInterval&) override;
0075 KeyedProxiesVector registerProxies(EventSetupRecordKey const&, unsigned int iovIndex) override;
0076 void initConcurrentIOVs(EventSetupRecordKey const&, unsigned int nConcurrentIOVs) override;
0077
0078 std::set<edm::IOVSyncValue> setOfIOV_;
0079 const unsigned int iterations_;
0080 const double pi_;
0081 unsigned int expectedNumberOfConcurrentIOVs_;
0082 unsigned int nConcurrentIOVs_ = 0;
0083 bool checkIOVInitialization_;
0084 };
0085
0086 TestESSourceTestProxy::TestESSourceTestProxy(TestESSource* testESSource)
0087 : edm::eventsetup::ESSourceDataProxyNonConcurrentBase(&testESSource->queue_, &testESSource->mutex_),
0088 testESSource_(testESSource) {}
0089
0090 void TestESSourceTestProxy::prefetch(edm::eventsetup::DataKey const& iKey, edm::EventSetupRecordDetails iRecord) {
0091 ++testESSource_->count_;
0092 if (testESSource_->count_.load() > 1) {
0093 throw cms::Exception("TestFailure") << "TestESSourceTestProxy::getImpl,"
0094 << " functions in mutex should not run concurrently";
0095 }
0096 testESSource_->busyWait("getImpl");
0097
0098 edm::ValidityInterval iov = iRecord.validityInterval();
0099 edm::LogAbsolute("TestESSourceTestProxy")
0100 << "TestESSoureTestProxy::getImpl startIOV = " << iov.first().luminosityBlockNumber()
0101 << " endIOV = " << iov.last().luminosityBlockNumber() << " IOV index = " << iRecord.iovIndex()
0102 << " cache identifier = " << iRecord.cacheIdentifier();
0103
0104 iovTestInfo_.iovStartLumi_ = iov.first().luminosityBlockNumber();
0105 iovTestInfo_.iovEndLumi_ = iov.last().luminosityBlockNumber();
0106 iovTestInfo_.iovIndex_ = iRecord.iovIndex();
0107 iovTestInfo_.cacheIdentifier_ = iRecord.cacheIdentifier();
0108
0109 --testESSource_->count_;
0110 }
0111
0112 void const* TestESSourceTestProxy::getAfterPrefetchImpl() const { return &iovTestInfo_; }
0113
0114 void TestESSourceTestProxy::initializeForNewIOV() {
0115 edm::LogAbsolute("TestESSourceTestProxy::initializeForNewIOV") << "TestESSourceTestProxy::initializeForNewIOV";
0116 ++testESSource_->count2_;
0117 }
0118
0119 TestESSource::TestESSource(edm::ParameterSet const& pset)
0120 : count_(0),
0121 count1_(0),
0122 count2_(0),
0123 iterations_(pset.getParameter<unsigned int>("iterations")),
0124 pi_(std::acos(-1)),
0125 expectedNumberOfConcurrentIOVs_(pset.getParameter<unsigned int>("expectedNumberOfConcurrentIOVs")),
0126 checkIOVInitialization_(pset.getParameter<bool>("checkIOVInitialization")) {
0127 std::vector<unsigned int> temp(pset.getParameter<std::vector<unsigned int>>("firstValidLumis"));
0128 for (auto val : temp) {
0129 setOfIOV_.insert(edm::IOVSyncValue(edm::EventID(1, val, 0)));
0130 }
0131
0132 findingRecord<ESTestRecordI>();
0133 usingRecord<ESTestRecordI>();
0134 }
0135
0136 TestESSource::~TestESSource() {}
0137
0138 void TestESSource::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0139 edm::ParameterSetDescription desc;
0140 std::vector<unsigned int> emptyVector;
0141 desc.add<unsigned int>("iterations", 10 * 1000 * 1000);
0142 desc.add<bool>("checkIOVInitialization", false);
0143 desc.add<unsigned int>("expectedNumberOfConcurrentIOVs", 0);
0144 desc.add<std::vector<unsigned int>>("firstValidLumis", emptyVector);
0145 descriptions.addDefault(desc);
0146 }
0147
0148 void TestESSource::setIntervalFor(EventSetupRecordKey const&,
0149 edm::IOVSyncValue const& syncValue,
0150 edm::ValidityInterval& iov) {
0151 std::lock_guard<std::mutex> guard(mutex_);
0152 if (checkIOVInitialization_) {
0153
0154
0155
0156 if (count1_ > 0 && count2_ + 1 != count1_) {
0157 throw cms::Exception("TestFailure") << "TestESSource::setIntervalFor,"
0158 << " unexpected number of IOV initializations";
0159 }
0160 }
0161 ++count_;
0162 ++count1_;
0163 if (count_.load() > 1) {
0164 throw cms::Exception("TestFailure") << "TestESSource::setIntervalFor,"
0165 << " functions in mutex should not run concurrently";
0166 }
0167 busyWait("setIntervalFor");
0168 iov = edm::ValidityInterval::invalidInterval();
0169
0170 if (setOfIOV_.empty()) {
0171 --count_;
0172 return;
0173 }
0174
0175 std::pair<std::set<edm::IOVSyncValue>::iterator, std::set<edm::IOVSyncValue>::iterator> itFound =
0176 setOfIOV_.equal_range(syncValue);
0177
0178 if (itFound.first == itFound.second) {
0179 if (itFound.first == setOfIOV_.begin()) {
0180
0181 --count_;
0182 return;
0183 }
0184
0185 --itFound.first;
0186 }
0187
0188 edm::IOVSyncValue endOfInterval = edm::IOVSyncValue::endOfTime();
0189 if (itFound.second != setOfIOV_.end()) {
0190 endOfInterval = edm::IOVSyncValue(
0191 edm::EventID(1, itFound.second->eventID().luminosityBlock() - 1, edm::EventID::maxEventNumber()));
0192 }
0193 iov = edm::ValidityInterval(*(itFound.first), endOfInterval);
0194 --count_;
0195 }
0196
0197 edm::eventsetup::DataProxyProvider::KeyedProxiesVector TestESSource::registerProxies(EventSetupRecordKey const&,
0198 unsigned int iovIndex) {
0199 if (expectedNumberOfConcurrentIOVs_ != 0 && nConcurrentIOVs_ != expectedNumberOfConcurrentIOVs_) {
0200 throw cms::Exception("TestFailure") << "TestESSource::registerProxies,"
0201 << " unexpected number of concurrent IOVs";
0202 }
0203 KeyedProxiesVector keyedProxiesVector;
0204
0205 edm::eventsetup::DataKey dataKey(edm::eventsetup::DataKey::makeTypeTag<IOVTestInfo>(), edm::eventsetup::IdTags(""));
0206 keyedProxiesVector.emplace_back(dataKey, std::make_shared<TestESSourceTestProxy>(this));
0207
0208 return keyedProxiesVector;
0209 }
0210
0211 void TestESSource::initConcurrentIOVs(EventSetupRecordKey const& key, unsigned int nConcurrentIOVs) {
0212 edm::LogAbsolute("TestESSource::initConcurrentIOVs")
0213 << "Start TestESSource::initConcurrentIOVs " << nConcurrentIOVs << " " << key.name();
0214 if (EventSetupRecordKey::makeKey<ESTestRecordI>() != key) {
0215 throw cms::Exception("TestFailure") << "TestESSource::initConcurrentIOVs,"
0216 << " unexpected EventSetupRecordKey";
0217 }
0218 if (expectedNumberOfConcurrentIOVs_ != 0 && nConcurrentIOVs != expectedNumberOfConcurrentIOVs_) {
0219 throw cms::Exception("TestFailure") << "TestESSource::initConcurrentIOVs,"
0220 << " unexpected number of concurrent IOVs";
0221 }
0222 nConcurrentIOVs_ = nConcurrentIOVs;
0223 }
0224
0225 void TestESSource::busyWait(char const* msg) const {
0226 edm::LogAbsolute("TestESSource::busyWait") << "Start TestESSource::busyWait " << msg;
0227 double sum = 0.;
0228 const double stepSize = pi_ / iterations_;
0229 for (unsigned int i = 0; i < iterations_; ++i) {
0230 sum += stepSize * cos(i * stepSize);
0231 }
0232 edm::LogAbsolute("TestESSource::busyWait") << "Stop TestESSource::busyWait " << msg << " " << sum;
0233 }
0234 }
0235 using namespace edmtest;
0236 DEFINE_FWK_EVENTSETUP_SOURCE(TestESSource);