7 using namespace std::string_literals;
8 using namespace std::literals::string_view_literals;
12 enum class AlgState : size_t {
24 static constexpr std::array<std::string_view,8> s_algStateNames = {{
25 "INITIAL"sv,
"CONTROLREADY"sv,
"DATAREADY"sv,
"RESOURCELESS"sv,
"SCHEDULED"sv,
"EVTACCEPTED"sv,
"EVTREJECTED"sv,
"ERROR"sv
28 static constexpr std::array<size_t,8> s_algStateNumbers = {0,1,2,3,4,5,6,7};
30 static constexpr std::array<size_t,4> s_activeAlgStateNumbers = {
31 static_cast<size_t>(AlgState::CONTROLREADY),
32 static_cast<size_t>(AlgState::DATAREADY),
33 static_cast<size_t>(AlgState::RESOURCELESS),
34 static_cast<size_t>(AlgState::SCHEDULED)
37 template<
typename Ta,
typename Tb> constexpr
double divAsDouble(
const Ta&
a,
const Tb&
b) {
38 return static_cast<double>(
a) /
static_cast<double>(
b);
44 : base_class(
name, svcLoc) {}
49 return StatusCode::SUCCESS;
59 return StatusCode::FAILURE;
65 const int numSlots = std::stoi( serviceLocator()->service(
"EventDataSvc").as<IProperty>()->
getProperty(
"NSlots").
toString() );
68 if (
bool expected =
false; not
m_running.compare_exchange_strong(expected,
true)) {
69 ATH_MSG_ERROR(
"startMonitoring called but it is already running");
70 return StatusCode::FAILURE;
75 auto monCallback = [
this,
numThreads, numSlots](IScheduler::OccupancySnapshot snap) ->
void {
79 const size_t thisSnapCounter = std::chrono::duration_cast<std::chrono::milliseconds>(wallTime).count() /
m_monIntervalMillisec.value();
81 const int periodsSinceLastSnap = thisSnapCounter - lastSnapCounter;
84 if (periodsSinceLastSnap <= 0) {
85 ATH_MSG_DEBUG(
"Discarding snap because periodsSinceLastSnap=" << periodsSinceLastSnap <<
" is not positive");
90 std::vector<int> stateTotalCounts(
static_cast<size_t>(AlgState::MAXVALUE), 0);
91 for (
size_t slot=0; slot < snap.states.size(); ++slot) {
92 for (
size_t state=0; state < snap.states[slot].size(); ++state) {
93 stateTotalCounts[state] += snap.states[slot][state];
100 std::vector<Monitored::Scalar<int>> mon_stateCounts;
101 std::vector<Monitored::Scalar<double>> mon_stateCountsOverThreads;
102 std::vector<Monitored::Scalar<double>> mon_stateCountsOverSlots;
103 std::vector<Monitored::Scalar<double>> mon_stateCountsOverActive;
104 mon_stateCounts.reserve(
static_cast<size_t>(AlgState::MAXVALUE));
105 mon_stateCountsOverThreads.reserve(
static_cast<size_t>(AlgState::MAXVALUE));
106 mon_stateCountsOverSlots.reserve(
static_cast<size_t>(AlgState::MAXVALUE));
107 mon_stateCountsOverActive.reserve(
static_cast<size_t>(AlgState::MAXVALUE));
109 for (
size_t i : s_activeAlgStateNumbers) {
110 activeCount += stateTotalCounts[
i];
112 for (
size_t i : s_algStateNumbers) {
113 mon_stateCounts.emplace_back(s_algStateNames[
i].
data(), stateTotalCounts[
i]);
114 mon_stateCountsOverThreads.emplace_back(s_algStateNames[
i].
data()+
"_Over_Threads"s, divAsDouble(stateTotalCounts[
i],
numThreads));
115 mon_stateCountsOverSlots.emplace_back(s_algStateNames[
i].
data()+
"_Over_Slots"s, divAsDouble(stateTotalCounts[
i], numSlots));
116 double toActive = (activeCount > 0) ? divAsDouble(stateTotalCounts[
i], activeCount) : 0;
117 mon_stateCountsOverActive.emplace_back(s_algStateNames[
i].
data()+
"_Over_Active"s, toActive);
125 std::vector<std::reference_wrapper<Monitored::IMonitoredVariable>> allMonVars;
126 allMonVars.reserve(6 +
127 mon_stateCounts.size() +
128 mon_stateCountsOverThreads.size() +
129 mon_stateCountsOverSlots.size() +
130 mon_stateCountsOverActive.size());
133 for (
size_t snapNumber=lastSnapCounter+1; snapNumber<=thisSnapCounter; ++snapNumber) {
137 allMonVars.insert(allMonVars.end(), mon_stateCounts.begin(), mon_stateCounts.end());
138 allMonVars.insert(allMonVars.end(), mon_stateCountsOverThreads.begin(), mon_stateCountsOverThreads.end());
139 allMonVars.insert(allMonVars.end(), mon_stateCountsOverSlots.begin(), mon_stateCountsOverSlots.end());
140 allMonVars.insert(allMonVars.end(), mon_stateCountsOverActive.begin(), mon_stateCountsOverActive.end());
141 allMonVars.insert(allMonVars.end(), {mon_stateNumber, mon_stateTotalCounts, mon_freeSlots, mon_freeSlotsFrac,
142 mon_snapNumber, mon_wallTimeSec});
155 return StatusCode::SUCCESS;
160 if (
bool expected =
true; not
m_running.compare_exchange_strong(expected,
false)) {
162 return StatusCode::SUCCESS;
166 return StatusCode::SUCCESS;