File indexing completed on 2024-04-06 12:12:35
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/ESSourceProductResolverNonConcurrentBase.h"
0017 #include "FWCore/Framework/interface/ESProductResolverProvider.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/interface/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 TestESSourceTestResolver : public edm::eventsetup::ESSourceProductResolverNonConcurrentBase {
0044 public:
0045 TestESSourceTestResolver(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::ESProductResolverProvider, public edm::EventSetupRecordIntervalFinder {
0057 public:
0058 using EventSetupRecordKey = edm::eventsetup::EventSetupRecordKey;
0059 explicit TestESSource(edm::ParameterSet const&);
0060 ~TestESSource() override;
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 KeyedResolversVector registerResolvers(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 TestESSourceTestResolver::TestESSourceTestResolver(TestESSource* testESSource)
0087 : edm::eventsetup::ESSourceProductResolverNonConcurrentBase(&testESSource->queue_, &testESSource->mutex_),
0088 testESSource_(testESSource) {}
0089
0090 void TestESSourceTestResolver::prefetch(edm::eventsetup::DataKey const& iKey, edm::EventSetupRecordDetails iRecord) {
0091 ++testESSource_->count_;
0092 if (testESSource_->count_.load() > 1) {
0093 throw cms::Exception("TestFailure") << "TestESSourceTestResolver::getImpl,"
0094 << " functions in mutex should not run concurrently";
0095 }
0096 testESSource_->busyWait("getImpl");
0097
0098 edm::ValidityInterval iov = iRecord.validityInterval();
0099 edm::LogAbsolute("TestESSourceTestResolver")
0100 << "TestESSoureTestResolver::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* TestESSourceTestResolver::getAfterPrefetchImpl() const { return &iovTestInfo_; }
0113
0114 void TestESSourceTestResolver::initializeForNewIOV() {
0115 edm::LogAbsolute("TestESSourceTestResolver::initializeForNewIOV")
0116 << "TestESSourceTestResolver::initializeForNewIOV";
0117 ++testESSource_->count2_;
0118 }
0119
0120 TestESSource::TestESSource(edm::ParameterSet const& pset)
0121 : count_(0),
0122 count1_(0),
0123 count2_(0),
0124 iterations_(pset.getParameter<unsigned int>("iterations")),
0125 pi_(std::acos(-1)),
0126 expectedNumberOfConcurrentIOVs_(pset.getParameter<unsigned int>("expectedNumberOfConcurrentIOVs")),
0127 checkIOVInitialization_(pset.getParameter<bool>("checkIOVInitialization")) {
0128 std::vector<unsigned int> temp(pset.getParameter<std::vector<unsigned int>>("firstValidLumis"));
0129 for (auto val : temp) {
0130 setOfIOV_.insert(edm::IOVSyncValue(edm::EventID(1, val, 0)));
0131 }
0132
0133 findingRecord<ESTestRecordI>();
0134 usingRecord<ESTestRecordI>();
0135 }
0136
0137 TestESSource::~TestESSource() {}
0138
0139 void TestESSource::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0140 edm::ParameterSetDescription desc;
0141 std::vector<unsigned int> emptyVector;
0142 desc.add<unsigned int>("iterations", 10 * 1000 * 1000);
0143 desc.add<bool>("checkIOVInitialization", false);
0144 desc.add<unsigned int>("expectedNumberOfConcurrentIOVs", 0);
0145 desc.add<std::vector<unsigned int>>("firstValidLumis", emptyVector);
0146 descriptions.addDefault(desc);
0147 }
0148
0149 void TestESSource::setIntervalFor(EventSetupRecordKey const&,
0150 edm::IOVSyncValue const& syncValue,
0151 edm::ValidityInterval& iov) {
0152 std::lock_guard<std::mutex> guard(mutex_);
0153 if (checkIOVInitialization_) {
0154
0155
0156
0157 if (count1_ > 0 && count2_ + 1 != count1_) {
0158 throw cms::Exception("TestFailure") << "TestESSource::setIntervalFor,"
0159 << " unexpected number of IOV initializations";
0160 }
0161 }
0162 ++count_;
0163 ++count1_;
0164 if (count_.load() > 1) {
0165 throw cms::Exception("TestFailure") << "TestESSource::setIntervalFor,"
0166 << " functions in mutex should not run concurrently";
0167 }
0168 busyWait("setIntervalFor");
0169 iov = edm::ValidityInterval::invalidInterval();
0170
0171 if (setOfIOV_.empty()) {
0172 --count_;
0173 return;
0174 }
0175
0176 std::pair<std::set<edm::IOVSyncValue>::iterator, std::set<edm::IOVSyncValue>::iterator> itFound =
0177 setOfIOV_.equal_range(syncValue);
0178
0179 if (itFound.first == itFound.second) {
0180 if (itFound.first == setOfIOV_.begin()) {
0181
0182 --count_;
0183 return;
0184 }
0185
0186 --itFound.first;
0187 }
0188
0189 edm::IOVSyncValue endOfInterval = edm::IOVSyncValue::endOfTime();
0190 if (itFound.second != setOfIOV_.end()) {
0191 endOfInterval = edm::IOVSyncValue(
0192 edm::EventID(1, itFound.second->eventID().luminosityBlock() - 1, edm::EventID::maxEventNumber()));
0193 }
0194 iov = edm::ValidityInterval(*(itFound.first), endOfInterval);
0195 --count_;
0196 }
0197
0198 edm::eventsetup::ESProductResolverProvider::KeyedResolversVector TestESSource::registerResolvers(
0199 EventSetupRecordKey const&, unsigned int iovIndex) {
0200 if (expectedNumberOfConcurrentIOVs_ != 0 && nConcurrentIOVs_ != expectedNumberOfConcurrentIOVs_) {
0201 throw cms::Exception("TestFailure") << "TestESSource::registerResolvers,"
0202 << " unexpected number of concurrent IOVs";
0203 }
0204 KeyedResolversVector keyedResolversVector;
0205
0206 edm::eventsetup::DataKey dataKey(edm::eventsetup::DataKey::makeTypeTag<IOVTestInfo>(), edm::eventsetup::IdTags(""));
0207 keyedResolversVector.emplace_back(dataKey, std::make_shared<TestESSourceTestResolver>(this));
0208
0209 return keyedResolversVector;
0210 }
0211
0212 void TestESSource::initConcurrentIOVs(EventSetupRecordKey const& key, unsigned int nConcurrentIOVs) {
0213 edm::LogAbsolute("TestESSource::initConcurrentIOVs")
0214 << "Start TestESSource::initConcurrentIOVs " << nConcurrentIOVs << " " << key.name();
0215 if (EventSetupRecordKey::makeKey<ESTestRecordI>() != key) {
0216 throw cms::Exception("TestFailure") << "TestESSource::initConcurrentIOVs,"
0217 << " unexpected EventSetupRecordKey";
0218 }
0219 if (expectedNumberOfConcurrentIOVs_ != 0 && nConcurrentIOVs != expectedNumberOfConcurrentIOVs_) {
0220 throw cms::Exception("TestFailure") << "TestESSource::initConcurrentIOVs,"
0221 << " unexpected number of concurrent IOVs";
0222 }
0223 nConcurrentIOVs_ = nConcurrentIOVs;
0224 }
0225
0226 void TestESSource::busyWait(char const* msg) const {
0227 edm::LogAbsolute("TestESSource::busyWait") << "Start TestESSource::busyWait " << msg;
0228 double sum = 0.;
0229 const double stepSize = pi_ / iterations_;
0230 for (unsigned int i = 0; i < iterations_; ++i) {
0231 sum += stepSize * cos(i * stepSize);
0232 }
0233 edm::LogAbsolute("TestESSource::busyWait") << "Stop TestESSource::busyWait " << msg << " " << sum;
0234 }
0235 }
0236 using namespace edmtest;
0237 DEFINE_FWK_EVENTSETUP_SOURCE(TestESSource);