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