SharedResource.cc
Go to the documentation of this file.
4 #include "cetlib_except/demangle.h"
5 #include "hep_concurrency/SerialTaskQueue.h"
6 
7 #include <algorithm>
8 #include <cassert>
9 #include <map>
10 #include <memory>
11 #include <string>
12 #include <utility>
13 #include <vector>
14 
15 using namespace hep::concurrency;
16 using namespace std::string_literals;
17 
18 namespace {
20  error_context(std::string const& name)
21  {
22  return "An error occurred while attempting to register the shared resource '"s +
23  name + "'.\n";
24  }
25 }
26 
27 namespace art::detail {
28  SharedResource_t::SharedResource_t(std::string const& resource_name,
29  bool const demangle)
30  : name{demangle ? cet::demangle_symbol(resource_name) : resource_name}
31  {}
32 
33  SharedResource_t const LegacyResource{"__legacy__", false};
34 
36  {
37  // Propulate queues for known shared resources. Creating these
38  // slots does *not* automatically introduce synchronization.
39  // Synchronization is enabled based on the resource-names argument
40  // presented to the 'createQueues' member function.
41  registerSharedResource(LegacyResource);
42  }
43 
44  void
46  {
47  if (frozen_) {
48  throw Exception{errors::LogicError, error_context(name)}
49  << "The shared-resources registry has been frozen. All 'serialize' "
50  "calls\n"
51  << "must be made in the constructor of a shared module and no later.\n";
52  }
53  }
54 
55  void
56  SharedResources::registerSharedResources(std::set<std::string> const& names)
57  {
58  cet::for_all(names, [this](auto const& name) { register_resource(name); });
59  }
60 
61  void
63  {
64  register_resource(resource.name);
65  }
66 
67  void
69  {
70  ensure_not_frozen(name);
71  ++resourceCounts_[name];
72  if (name == LegacyResource.name) {
73  ++nLegacy_;
74  }
75  }
76 
77  void
78  SharedResources::freeze(tbb::task_group& group)
79  {
80  frozen_ = true;
81 
82  std::vector<std::pair<unsigned, std::string>> resources_sorted_by_count;
83  for (auto const& [name, count] : resourceCounts_) {
84  // Make sure all non-legacy resources have a higher count, which
85  // makes legacy always the first queue.
86  auto const offset = (name == LegacyResource.name) ? 0u : nLegacy_;
87  resources_sorted_by_count.emplace_back(count + offset, name);
88  }
89  cet::sort_all(resources_sorted_by_count, [](auto const& a, auto const& b) {
90  return a.first < b.first;
91  });
92 
93  assert(empty(sortedResources_));
94  for (auto const& pr : resources_sorted_by_count) {
95  sortedResources_.emplace_back(pr.second,
96  std::make_shared<SerialTaskQueue>(group));
97  }
98 
99  // Not needed any more now that we have a sorted list of resources.
100  resourceCounts_.clear();
101  }
102 
103  std::vector<std::shared_ptr<SerialTaskQueue>>
105  std::vector<std::string> const& resourceNames) const
106  {
107  std::vector<queue_ptr_t> result;
108  if (cet::search_all(resourceNames, LegacyResource.name)) {
109  // We do not trust legacy modules as they may be accessing one
110  // of the shared resources without our knowledge. We therefore
111  // isolate them from all other shared modules (and each other).
112  for (auto const& pr : sortedResources_) {
113  result.push_back(pr.second);
114  }
115  } else {
116  // Not for a legacy module, get the queues for the named
117  // resources.
118  for (auto const& name : resourceNames) {
119  auto it =
120  std::find_if(begin(sortedResources_),
121  end(sortedResources_),
122  [&name](auto const& pr) { return pr.first == name; });
123  assert(it != sortedResources_.end());
124  result.push_back(it->second);
125  }
126  }
127 
128  assert(not empty(result));
129  return result;
130  }
131 
132 } // namespace art
static QCString name
Definition: declinfo.cpp:673
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
void ensure_not_frozen(std::string const &name)
std::string demangle(T const *=nullptr)
Outputs a demangled name for type T.
Definition: DebugUtils.h:56
static QCString result
std::string string
Definition: nybbler.cc:12
void register_resource(std::string const &name)
void freeze(tbb::task_group &group)
void sort_all(RandCont &)
SharedResource_t const LegacyResource
bool search_all(FwdCont const &, Datum const &)
const double a
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
auto for_all(FwdCont &, Func)
static bool * b
Definition: config.cpp:1043
void registerSharedResources(std::set< std::string > const &names)
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:72
static std::vector< std::string > const names
Definition: FragmentType.hh:8
std::vector< queue_ptr_t > createQueues(std::vector< std::string > const &resourceNames) const
static QCString * s
Definition: config.cpp:1042
decltype(auto) constexpr empty(T &&obj)
ADL-aware version of std::empty.
Definition: StdUtils.h:97
void registerSharedResource(detail::SharedResource_t const &)