CMS 3D CMS Logo

MessageSender.cc
Go to the documentation of this file.
6 
7 #include <algorithm>
8 #include <cassert>
9 #include <vector>
10 #include <limits>
11 #include <atomic>
12 
13 #include <functional>
14 #include "tbb/concurrent_unordered_map.h"
15 
16 #define TRACE_DROP
17 #ifdef TRACE_DROP
18 #include <iostream>
19 #endif
20 
21 // Change log
22 //
23 // 1 mf 8/25/08 keeping the error summary information for
24 // LoggedErrorsSummary()
25 //
26 // 2 mf 11/2/10 Use new moduleContext method of MessageDrop:
27 // see MessageServer/src/MessageLogger.cc change 17.
28 //
29 
30 using namespace edm;
31 
32 namespace {
33  //Helper class used as 'key' to the thread safe map storing the
34  // per event log error and log warning messages
35  struct ErrorSummaryMapKey {
39 
40  bool operator<(ErrorSummaryMapKey const& iOther) const {
41  int comp = severity.getLevel() - iOther.severity.getLevel();
42  if (0 == comp) {
43  comp = category.compare(iOther.category);
44  if (comp == 0) {
45  comp = module.compare(iOther.module);
46  }
47  }
48  return comp < 0;
49  }
50 
51  bool operator==(ErrorSummaryMapKey const& iOther) const {
52  return ((iOther.category == category) and (iOther.module == module) and
53  (severity.getLevel() == iOther.severity.getLevel()));
54  }
55  size_t smallHash() const {
56  std::hash<std::string> h;
57 
58  return h(category + module + severity.getSymbol());
59  }
60 
61  struct key_hash {
62  std::size_t operator()(ErrorSummaryMapKey const& iKey) const { return iKey.smallHash(); }
63  };
64  };
65 
66  class AtomicUnsignedInt {
67  public:
68  AtomicUnsignedInt() : value_(0) {}
69  AtomicUnsignedInt(AtomicUnsignedInt const& r) : value_(r.value_.load(std::memory_order_acquire)) {}
70  std::atomic<unsigned int>& value() { return value_; }
71  std::atomic<unsigned int> const& value() const { return value_; }
72 
73  private:
74  std::atomic<unsigned int> value_;
75  };
76 
77 } // namespace
78 
79 CMS_THREAD_SAFE static std::atomic<bool> errorSummaryIsBeingKept{false};
80 //Each item in the vector is reserved for a different Stream
81 CMS_THREAD_SAFE static std::vector<
82  tbb::concurrent_unordered_map<ErrorSummaryMapKey, AtomicUnsignedInt, ErrorSummaryMapKey::key_hash>>
84 
85 MessageSender::MessageSender(ELseverityLevel const& sev, ELstring const& id, bool verbatim, bool suppressed)
86  : errorobj_p(suppressed ? nullptr : new ErrorObj(sev, id, verbatim), ErrorObjDeleter()) {
87  //std::cout << "MessageSender ctor; new ErrorObj at: " << errorobj_p << '\n';
88 }
89 
90 // This destructor must not be permitted to throw. A
91 // boost::thread_resoruce_error is thrown at static destruction time,
92 // if the MessageLogger library is loaded -- even if it is not used.
94  if (errorObjPtr == nullptr) {
95  return;
96  }
97  try {
98  //std::cout << "MessageSender dtor; ErrorObj at: " << errorobj_p << '\n';
99 
100  // surrender ownership of our ErrorObj, transferring ownership
101  // (via the intermediate MessageLoggerQ) to the MessageLoggerScribe
102  // that will (a) route the message text to its destination(s)
103  // and will then (b) dispose of the ErrorObj
104 
106  if (drop) {
107  errorObjPtr->setModule(drop->moduleContext()); // change log
108  errorObjPtr->setContext(drop->runEvent);
109  }
110 #ifdef TRACE_DROP
111  if (!drop)
112  std::cerr << "MessageSender::~MessageSender() - Null drop pointer \n";
113 #endif
114  // change log 1
115  if (errorSummaryIsBeingKept.load(std::memory_order_acquire) && errorObjPtr->xid().severity >= ELwarning && drop &&
117  auto& errorSummaryMap = errorSummaryMaps[drop->streamID];
118 
119  ELextendedID const& xid = errorObjPtr->xid();
120  ErrorSummaryMapKey key{xid.id, xid.module, xid.severity};
121  auto i = errorSummaryMap.find(key);
122  if (i != errorSummaryMap.end()) {
123  i->second.value().fetch_add(1, std::memory_order_acq_rel); // same as ++errorSummaryMap[key]
124  } else {
125  errorSummaryMap[key].value().store(1, std::memory_order_release);
126  }
127  }
128 
129  MessageLoggerQ::MLqLOG(errorObjPtr);
130  } catch (...) {
131  // nothing to do
132 
133  // for test that removal of thread-involved static works,
134  // simply throw here, then run in trivial_main in totalview
135  // and Next or Step so that the exception would be detected.
136  // That test has been done 12/14/07.
137  }
138 }
140 
141 //The following functions are declared here rather than in
142 // LoggedErrorsSummary.cc because only MessageSender and these
143 // functions interact with the statics errorSummaryIsBeingKept and
144 // errorSummaryMaps. By putting them into the same .cc file the
145 // statics can be file scoped rather than class scoped and therefore
146 // better encapsulated.
147 namespace edm {
148 
150  bool ret = errorSummaryIsBeingKept.exchange(true, std::memory_order_acq_rel);
151  return ret;
152  }
153 
155  bool ret = errorSummaryIsBeingKept.exchange(false, std::memory_order_acq_rel);
156  return ret;
157  }
158 
159  bool FreshErrorsExist(unsigned int iStreamID) {
160  assert(iStreamID < errorSummaryMaps.size());
161  return !errorSummaryMaps[iStreamID].empty();
162  }
163 
164  std::vector<ErrorSummaryEntry> LoggedErrorsSummary(unsigned int iStreamID) {
165  assert(iStreamID < errorSummaryMaps.size());
166  auto const& errorSummaryMap = errorSummaryMaps[iStreamID];
167  std::vector<ErrorSummaryEntry> v;
168  auto end = errorSummaryMap.end();
169  for (auto i = errorSummaryMap.begin(); i != end; ++i) {
170  auto const& key = i->first;
171  ErrorSummaryEntry e{key.category, key.module, key.severity};
172 
173  e.count = i->second.value().load(std::memory_order_acquire);
174  v.push_back(e);
175  }
176  std::sort(v.begin(), v.end());
177  return v;
178  }
179 
180  void clearLoggedErrorsSummary(unsigned int iStreamID) {
181  assert(iStreamID < errorSummaryMaps.size());
182  errorSummaryMaps[iStreamID].clear();
183  }
184 
185  void setMaxLoggedErrorsSummaryIndicies(unsigned int iMax) { errorSummaryMaps.resize(iMax); }
186 
187  std::vector<ErrorSummaryEntry> LoggedErrorsOnlySummary(unsigned int iStreamID) { // ChangeLog 2
188  std::vector<ErrorSummaryEntry> v;
189  assert(iStreamID < errorSummaryMaps.size());
190  auto const& errorSummaryMap = errorSummaryMaps[iStreamID];
191  auto end = errorSummaryMap.end();
192  for (auto i = errorSummaryMap.begin(); i != end; ++i) {
193  auto const& key = i->first;
194  if (key.severity >= edm::ELerror) {
195  ErrorSummaryEntry e{key.category, key.module, key.severity};
196  e.count = i->second.value().load(std::memory_order_acquire);
197  v.push_back(e);
198  }
199  }
200  std::sort(v.begin(), v.end());
201  return v;
202  }
203 
204 } // end namespace edm
bool operator<(DetSet< T > const &x, DetSet< T > const &y)
Definition: DetSet.h:92
static std::vector< tbb::concurrent_unordered_map< ErrorSummaryMapKey, AtomicUnsignedInt, ErrorSummaryMapKey::key_hash > > errorSummaryMaps
ELseverityLevel severity
Definition: ELextendedID.h:29
FWCore Framework interface EventSetupRecordImplementation h
Helper function to determine trigger accepts.
bool EnableLoggedErrorsSummary()
#define nullptr
static MessageDrop * instance()
Definition: MessageDrop.cc:59
void operator()(ErrorObj *errorObjPtr)
void clearLoggedErrorsSummary(unsigned int iStreamID)
void setMaxLoggedErrorsSummaryIndicies(unsigned int iMax)
ELslProxy< ELwarningGen > const ELwarning
bool FreshErrorsExist(unsigned int iStreamID)
bool DisableLoggedErrorsSummary()
virtual void setContext(const ELstring &context)
Definition: ErrorObj.cc:167
const ELstring getSymbol() const
const ELextendedID & xid() const
Definition: ErrorObj.cc:133
bool operator==(debugging_allocator< X > const &, debugging_allocator< Y > const &) noexcept
unsigned int streamID
Definition: MessageDrop.h:101
ELslProxy< ELerrorGen > const ELerror
#define CMS_THREAD_SAFE
#define end
Definition: vmac.h:39
std::string moduleContext()
Definition: MessageDrop.cc:195
std::vector< ErrorSummaryEntry > LoggedErrorsOnlySummary(unsigned int iStreamID)
const int drop
static std::atomic< bool > errorSummaryIsBeingKept
static void MLqLOG(ErrorObj *p)
HLT enums.
std::vector< ErrorSummaryEntry > LoggedErrorsSummary(unsigned int iStreamID)
std::string runEvent
Definition: MessageDrop.h:100
std::string ELstring
Definition: ELstring.h:21
Definition: vlib.h:208
virtual void setModule(const ELstring &module)
Definition: ErrorObj.cc:165