CMS 3D CMS Logo

SharedResourcesRegistry.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: FWCore/Framework
4 // Class : SharedResourcesRegistry
5 //
6 // Implementation:
7 // [Notes on implementation]
8 //
9 // Original Author: Chris Jones
10 // Created: Sun, 06 Oct 2013 15:48:50 GMT
11 //
12 
13 // system include files
14 #include <algorithm>
15 #include <cassert>
16 
17 // user include files
20 
21 namespace edm {
22 
24 
27  static SharedResourcesRegistry s_instance;
28  return &s_instance;
29  }
30 
32  }
33 
34  void
36 
37  auto& queueAndCounter = resourceMap_[resourceName];
38 
39  if(resourceName == kLegacyModuleResourceName) {
40  ++nLegacy_;
41  for(auto & resource : resourceMap_) {
42  if(!resource.second.first) {
43  resource.second.first = std::make_shared<SerialTaskQueue>();
44  }
45  ++resource.second.second;
46  }
47  } else {
48  // count the number of times the resource was registered
49  ++queueAndCounter.second;
50 
51  // When first registering a nonlegacy resource, we have to
52  // account for any legacy resource registrations already made.
53  if(queueAndCounter.second == 1) {
54  if(nLegacy_ > 0U) {
55  queueAndCounter.first = std::make_shared<SerialTaskQueue>();
56  queueAndCounter.second += nLegacy_;
57  }
58  // If registering a nonlegacy resource the second time and
59  // the legacy resource has not been registered yet,
60  // we know we will need the queue so go ahead and create it.
61  } else if(queueAndCounter.second == 2) {
62  queueAndCounter.first = std::make_shared<SerialTaskQueue>();
63  }
64  }
65  }
66 
67  std::pair<SharedResourcesAcquirer, std::shared_ptr<std::recursive_mutex>>
70  resourceForDelayedReader_ = std::make_shared<std::recursive_mutex>(); // propagate_const<T> has no reset() function
71  queueForDelayedReader_ = std::make_shared<SerialTaskQueue>();
72  }
73 
74  std::vector<std::shared_ptr<SerialTaskQueue>> queues = {get_underlying(queueForDelayedReader_)};
75  return std::make_pair(SharedResourcesAcquirer(std::move(queues)),get_underlying(resourceForDelayedReader_));
76  }
77 
79  SharedResourcesRegistry::createAcquirer(std::vector<std::string> const& resourceNames) const {
80 
81  // The acquirer will acquire the shared resources declared by a module
82  // so that only it can use those resources while it runs. The other
83  // modules using the same resource will not be run until the module
84  // that acquired the resources completes its task.
85 
86  // The legacy shared resource is special.
87  // Legacy modules cannot run concurrently with each other or
88  // any other module that has declared any shared resource. Treat
89  // one modules that call usesResource with no argument in the
90  // same way.
91 
92  // Sort by how often used and then by name
93  // Consistent sorting avoids deadlocks and this particular order optimizes performance
94  std::map<std::pair<unsigned int, std::string>, std::shared_ptr<SerialTaskQueue>> sortedResources;
95 
96  // Is this acquirer for a module that depends on the legacy shared resource?
97  if(std::find(resourceNames.begin(), resourceNames.end(), kLegacyModuleResourceName) != resourceNames.end()) {
98 
99  for(auto const& resource : resourceMap_) {
100  // It's redundant to declare legacy if the legacy modules
101  // all declare all the other resources, so just skip it.
102  // But if the only shared resource is the legacy resource don't skip it.
103  if(resource.first == kLegacyModuleResourceName && resourceMap_.size() > 1) continue;
104  //If only one module wants it, it really isn't shared
105  if(resource.second.second > 1) {
106  sortedResources.insert(std::make_pair(std::make_pair(resource.second.second, resource.first),resource.second.first));
107  }
108  }
109  // Handle cases where the module does not declare the legacy resource
110  } else {
111  for(auto const& name : resourceNames) {
112  auto resource = resourceMap_.find(name);
113  assert(resource != resourceMap_.end());
114  //If only one module wants it, it really isn't shared
115  if(resource->second.second > 1) {
116  sortedResources.insert(std::make_pair(std::make_pair(resource->second.second, resource->first),resource->second.first));
117  }
118  }
119  }
120 
121  std::vector<std::shared_ptr<SerialTaskQueue>> queues;
122  queues.reserve(sortedResources.size());
123  for(auto const& resource: sortedResources) {
124  queues.push_back(resource.second);
125  }
126  if(queues.empty()) {
127  //Calling code is depending on there being at least one shared queue
128  queues.reserve(1);
129  queues.push_back(std::make_shared<SerialTaskQueue>());
130  }
131 
132  return SharedResourcesAcquirer(std::move(queues));
133  }
134 }
edm::propagate_const< std::shared_ptr< SerialTaskQueue > > queueForDelayedReader_
std::map< std::string, std::pair< std::shared_ptr< SerialTaskQueue >, unsigned int > > resourceMap_
SharedResourcesAcquirer createAcquirer(std::vector< std::string > const &) const
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:20
T & get_underlying(propagate_const< T > &)
static SharedResourcesRegistry * instance()
edm::propagate_const< std::shared_ptr< std::recursive_mutex > > resourceForDelayedReader_
void registerSharedResource(const std::string &)
A resource name must be registered before it can be used in the createAcquirer call.
static const std::string kLegacyModuleResourceName
All legacy modules share this resource.
HLT enums.
std::pair< SharedResourcesAcquirer, std::shared_ptr< std::recursive_mutex > > createAcquirerForSourceDelayedReader()
def move(src, dest)
Definition: eostools.py:511