LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
TaskDebugMacros.cc
Go to the documentation of this file.
2 #include "tbb/concurrent_unordered_map.h"
3 // vim: set sw=2 expandtab :
4 
5 #include <cstdlib>
6 #include <iomanip>
7 
8 namespace {
9  std::string
10  banner(char const prefix)
11  {
12  std::ostringstream oss;
13  oss << std::string(5, prefix) << "> " << std::setw(6) << std::right
14  << std::this_thread::get_id() << std::left << " ";
15  return oss.str();
16  }
17 
18  std::string
19  schedule_to_str(art::ScheduleID const id)
20  {
21  if (id == art::ScheduleID{}) {
22  return std::string(4, ' ');
23  }
24  std::ostringstream oss;
25  oss << "[" << std::setw(2) << std::right << std::setfill('0') << id
26  << std::setfill(' ') << std::left << "]";
27  return oss.str();
28  }
29 
30  std::string
31  trimmed(std::string const& fcn_name, std::string const& pretty_fcn_name)
32  {
33  // Use rfind because c'tor will have a pretty function name like:
34  // art::Path::Path
35  auto const begin_fcn_name = pretty_fcn_name.rfind(fcn_name);
36  auto const begin_qualified_fcn_name =
37  pretty_fcn_name.find_last_of(' ', begin_fcn_name);
38  auto begin =
39  begin_qualified_fcn_name > begin_fcn_name ? 0 : begin_qualified_fcn_name;
40  // Remove art:: namespace qualification
41  if (auto const stripped_begin = pretty_fcn_name.find("art::", begin);
42  stripped_begin != std::string::npos) {
43  begin = stripped_begin + 5;
44  };
45  auto const substr_length = begin_fcn_name - begin;
46  return pretty_fcn_name.substr(begin, substr_length) + fcn_name;
47  }
48 
49  tbb::concurrent_unordered_map<art::ScheduleID, unsigned> indents;
50 
51  std::string
52  indent_for(std::string const& step, art::ScheduleID const sid)
53  {
54  auto it = indents.insert(std::make_pair(sid, 0)).first;
55  if (step == "Begin") {
56  auto const printed = it->second;
57  ++it->second;
58  return std::string(printed, ' ');
59  } else if (step == "End") {
60  auto const printed = --it->second;
61  return std::string(printed, ' ');
62  }
63  return std::string(it->second, ' ');
64  }
65 }
66 
67 namespace art {
68 
70  {
71  cvalue_ = getenv("ART_DEBUG_TASKS");
72  value_ = (cvalue_.load() == nullptr) ? 0 : atoi(cvalue_.load());
73  }
74 
76 
77  namespace detail {
78  MessageAccumulator::MessageAccumulator(char const banner_prefix,
79  std::string const& fcn_name,
80  std::string const& pretty_fcn_name,
81  ScheduleID const sid,
82  std::string const& step)
83  {
84  buffer_ << banner(banner_prefix) << schedule_to_str(sid) << " "
85  << indent_for(step, sid) << std::left << std::setw(6) << step
86  << trimmed(fcn_name, pretty_fcn_name);
87  }
88 
90  {
91  auto const user_message = usr_msg_.str();
92  if (not empty(user_message)) {
93  buffer_ << " - " << user_message;
94  }
95  buffer_ << '\n';
96  std::cerr << buffer_.str();
97  }
98  }
99 
100 } // namespace art
constexpr auto const & right(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:102
MessageAccumulator(char const banner_prefix, std::string const &fcn_name, std::string const &pretty_fcn_name, ScheduleID schedule_id=ScheduleID{}, std::string const &step=std::string(6, ' '))
DebugTasksValue debugTasks
std::atomic< int > value_
constexpr auto const & left(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:94
std::atomic< char const * > cvalue_
Definition: MVAAlg.h:12
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:69
decltype(auto) constexpr empty(T &&obj)
ADL-aware version of std::empty.
Definition: StdUtils.h:109