241 void set(
double deltaV,
bool early);
277 std::ostringstream
t;
283 std::ostringstream
t;
316 ret.
pss_ +=
static_cast<double>(
value) / 1024.;
325 return (current - past) / (double)count;
333 pg_size_(sysconf(_SC_PAGESIZE))
335 num_to_skip_(iPS.getUntrackedParameter<int>(
"ignoreTotal")),
336 showMallocInfo_(iPS.getUntrackedParameter<bool>(
"showMallocInfo")),
337 oncePerEventMode_(iPS.getUntrackedParameter<bool>(
"oncePerEventMode")),
338 jobReportOutputOnly_(iPS.getUntrackedParameter<bool>(
"jobReportOutputOnly")),
339 monitorPssAndPrivate_(iPS.getUntrackedParameter<bool>(
"monitorPssAndPrivate")),
342 smapsLineBuffer_(nullptr),
343 smapsLineBufferLen_(0),
346 moduleSummaryRequested_(iPS.getUntrackedParameter<bool>(
"moduleMemorySummary")),
347 measurementUnderway_(
false) {
350 std::ostringstream ost;
384 #ifndef __SANITIZE_ADDRESS__
410 LogWarning(
"MemoryCheck") <<
"Malloc options: " << mo <<
"\n";
440 descriptions.
add(
"SimpleMemoryCheck", desc);
446 std::ostringstream smapsNameOst;
447 smapsNameOst <<
"/proc/" << getpid() <<
"/smaps";
448 if ((
smapsFile_ = fopen(smapsNameOst.str().c_str(),
"r")) ==
nullptr) {
461 bool expected =
false;
463 std::shared_ptr<void> guard(
464 nullptr, [
this](
void const*) {
measurementUnderway_.store(
false, std::memory_order_release); });
470 bool expected =
false;
472 std::shared_ptr<void> guard(
473 nullptr, [
this](
void const*) {
measurementUnderway_.store(
false, std::memory_order_release); });
479 bool expected =
false;
481 std::shared_ptr<void> guard(
482 nullptr, [
this](
void const*) {
measurementUnderway_.store(
false, std::memory_order_release); });
488 bool expected =
false;
490 std::shared_ptr<void> guard(
491 nullptr, [
this](
void const*) {
measurementUnderway_.store(
false, std::memory_order_release); });
497 bool expected =
false;
499 std::shared_ptr<void> guard(
500 nullptr, [
this](
void const*) {
measurementUnderway_.store(
false, std::memory_order_release); });
508 <<
"MemoryReport> Peak virtual size " <<
eventT1_.
vsize <<
" Mbytes"
510 <<
" Key events increasing vsize: \n"
524 mmr <<
"ModuleMemoryReport> Each line has module label and: \n";
525 mmr <<
" (after early ignored events) \n";
526 mmr <<
" count of times module executed; average increase in vsize \n";
527 mmr <<
" maximum increase in vsize; event on which maximum occurred \n";
528 mmr <<
" (during early ignored events) \n";
529 mmr <<
" total and maximum vsize increases \n \n";
530 for (SignificantModulesMap::iterator im =
modules_.begin(); im !=
modules_.end(); ++im) {
534 mmr << im->first <<
": ";
550 #define SIMPLE_MEMORY_CHECK_ORIGINAL_XML_OUTPUT
551 #ifdef SIMPLE_MEMORY_CHECK_ORIGINAL_XML_OUTPUT
553 std::map<std::string, std::string> reportData;
586 struct mallinfo minfo = mallinfo();
587 reportData.insert(std::make_pair(
"HEAP_ARENA_SIZE_BYTES",
i2str(minfo.arena)));
588 reportData.insert(std::make_pair(
"HEAP_ARENA_N_UNUSED_CHUNKS",
i2str(minfo.ordblks)));
589 reportData.insert(std::make_pair(
"HEAP_TOP_FREE_BYTES",
i2str(minfo.keepcost)));
590 reportData.insert(std::make_pair(
"HEAP_MAPPED_SIZE_BYTES",
i2str(minfo.hblkhd)));
591 reportData.insert(std::make_pair(
"HEAP_MAPPED_N_CHUNKS",
i2str(minfo.hblks)));
592 reportData.insert(std::make_pair(
"HEAP_USED_BYTES",
i2str(minfo.uordblks)));
593 reportData.insert(std::make_pair(
"HEAP_UNUSED_BYTES",
i2str(minfo.fordblks)));
597 reportData.insert(std::make_pair(
"AverageGrowthRateVsize",
605 for (SignificantModulesMap::iterator im =
modules_.begin(); im !=
modules_.end(); ++im) {
617 reportData.insert(std::make_pair(label +
"MaxEarlyDeltaVsize",
d2str(m.
maxEarlyVsize)));
622 std::map<std::string, std::string> reportMemoryProperties;
624 if (FILE* fmeminfo = fopen(
"/proc/meminfo",
"r")) {
628 while (fgets(buf,
sizeof(buf), fmeminfo)) {
630 char*
token =
nullptr;
631 token = strtok_r(buf, space, &saveptr);
632 if (token !=
nullptr) {
633 value = atol(strtok_r(
nullptr, space, &saveptr));
635 reportMemoryProperties.insert(std::make_pair(category.substr(0, strlen(token) - 1),
i2str(value)));
643 reportSvc->reportPerformanceSummary(
"ApplicationMemory", reportData);
644 reportSvc->reportPerformanceSummary(
"SystemMemory", reportMemoryProperties);
647 #ifdef SIMPLE_MEMORY_CHECK_DIFFERENT_XML_OUTPUT
648 std::vector<std::string> reportData;
680 struct mallinfo minfo = mallinfo();
681 reportData.push_back(
mallOutput(
"HEAP_ARENA_SIZE_BYTES", minfo.arena));
682 reportData.push_back(
mallOutput(
"HEAP_ARENA_N_UNUSED_CHUNKS", minfo.ordblks));
683 reportData.push_back(
mallOutput(
"HEAP_TOP_FREE_BYTES", minfo.keepcost));
684 reportData.push_back(
mallOutput(
"HEAP_MAPPED_SIZE_BYTES", minfo.hblkhd));
685 reportData.push_back(
mallOutput(
"HEAP_MAPPED_N_CHUNKS", minfo.hblks));
686 reportData.push_back(
mallOutput(
"HEAP_USED_BYTES", minfo.uordblks));
687 reportData.push_back(
mallOutput(
"HEAP_UNUSED_BYTES", minfo.fordblks));
690 reportData.insert(std::make_pair(
"AverageGrowthRateVsize",
697 reportSvc->reportMemoryInfo(reportData);
704 bool expected =
false;
706 std::shared_ptr<void> guard(
707 nullptr, [
this](
void const*) {
measurementUnderway_.store(
false, std::memory_order_release); });
722 bool expectedMeasurementUnderway =
false;
723 if (
measurementUnderway_.compare_exchange_strong(expectedMeasurementUnderway,
true, std::memory_order_acq_rel)) {
724 std::shared_ptr<void> guard(
725 nullptr, [
this](
void const*) {
measurementUnderway_.store(
false, std::memory_order_release); });
726 bool expectedModuleMeasurementUnderway =
false;
740 bool expected =
false;
742 std::shared_ptr<void> guard(
743 nullptr, [
this](
void const*) {
measurementUnderway_.store(
false, std::memory_order_release); });
755 std::shared_ptr<void> guardModuleMeasurementUnderway(
757 bool expected =
false;
759 std::shared_ptr<void> guardMeasurementUnderway(
760 nullptr, [
this](
void const*) {
measurementUnderway_.store(
false, std::memory_order_release); });
868 LogWarning(
"MemoryCheck") <<
"MemoryCheck: " << type <<
" " << mdname <<
":" << mdlabel <<
" VSIZE "
873 struct mallinfo minfo = mallinfo();
875 LogWarning(
"MemoryCheck") <<
"MemoryCheck: " << type <<
" " << mdname <<
":" << mdlabel <<
" VSIZE "
879 <<
" HEAP-ARENA [ SIZE-BYTES " << minfo.arena <<
" N-UNUSED-CHUNKS "
880 << minfo.ordblks <<
" TOP-FREE-BYTES " << minfo.keepcost <<
" ]"
881 <<
" HEAP-MAPPED [ SIZE-BYTES " << minfo.hblkhd <<
" N-CHUNKS " << minfo.hblks
883 <<
" HEAP-USED-BYTES " << minfo.uordblks <<
" HEAP-UNUSED-BYTES "
900 #ifdef SIMPLE_MEMORY_CHECK_ORIGINAL_XML_OUTPUT
903 std::map<std::string, std::string>&
m)
const {
905 std::ostringstream os;
906 os << title <<
"-a-COUNT";
907 m.insert(std::make_pair(os.str(),
i2str(e.
count)));
910 std::ostringstream os;
911 os << title <<
"-b-RUN";
912 m.insert(std::make_pair(os.str(),
d2str(static_cast<double>(e.
event.
run()))));
915 std::ostringstream os;
916 os << title <<
"-c-EVENT";
917 m.insert(std::make_pair(os.str(),
d2str(static_cast<double>(e.
event.
event()))));
920 std::ostringstream os;
921 os << title <<
"-d-VSIZE";
922 m.insert(std::make_pair(os.str(),
d2str(e.
vsize)));
925 std::ostringstream os;
926 os << title <<
"-e-DELTV";
930 std::ostringstream os;
931 os << title <<
"-f-RSS";
932 m.insert(std::make_pair(os.str(),
d2str(e.
rss)));
936 std::ostringstream os;
937 os << title <<
"-g-PRIVATE";
941 std::ostringstream os;
942 os << title <<
"-h-PSS";
943 m.insert(std::make_pair(os.str(),
d2str(e.
pss)));
949 #ifdef SIMPLE_MEMORY_CHECK_DIFFERENT_XML_OUTPUT
951 std::ostringstream os;
952 os <<
" <" << title <<
">\n";
953 os <<
" " << e.count <<
": " << e.event;
954 os <<
" vsize " << e.vsize - e.deltaVsize <<
" + " << e.deltaVsize <<
" = " << e.vsize;
955 os <<
" rss: " << e.rss <<
"\n";
956 os <<
" </" << title <<
">\n";
961 std::ostringstream os;
962 os <<
" <" << title <<
">\n";
963 os <<
" " << n <<
"\n";
964 os <<
" </" << title <<
">\n";
988 <<
" rss = " << se.
rss <<
" delta = " << se.
deltaRss;
1012 #if defined(__linux__)
void watchPostModuleConstruction(PostModuleConstruction::slot_type const &iSlot)
EventNumber_t event() const
T getUntrackedParameter(std::string const &, T const &) const
void set_trim_thr(opt_type trim_thr)
static std::string i2str(int i)
std::string eventStatOutput(std::string title, SignificantEvent const &e) const
tuple ret
prodAgent to be discontinued
SignificantEvent eventDeltaRssT1_
void preSourceConstruction(const ModuleDescription &)
void set_mmap_max(opt_type mmap_max)
std::pair< ALIstring, ALIstring > pss
friend std::ostream & operator<<(std::ostream &os, SimpleMemoryCheck::SignificantEvent const &se)
ParameterDescriptionBase * addUntracked(U const &iLabel, T const &value)
size_t smapsLineBufferLen_
void watchPostEndJob(PostEndJob::slot_type const &iSlot)
edm::propagate_const< ProcInfo * > current_
static const char category[]
std::atomic< bool > measurementUnderway_
SignificantEvent eventT1_
void set_mmap_thr(opt_type mmap_thr)
void watchPreModuleEvent(PreModuleEvent::slot_type const &iSlot)
void updateEventStats(edm::EventID const &e)
ProcInfoFetcher piFetcher_
void watchPostEvent(PostEvent::slot_type const &iSlot)
std::atomic< bool > moduleMeasurementUnderway_
void watchPreSourceConstruction(PreSourceConstruction::slot_type const &iSlot)
void watchPostSourceConstruction(PostSourceConstruction::slot_type const &iSlot)
SignificantEvent eventRssT2_
SignificantEvent eventL1_
std::string const & moduleName() const
void set(double deltaV, bool early)
void watchPostModuleEvent(PostModuleEvent::slot_type const &iSlot)
void watchPostSourceEvent(PostSourceEvent::slot_type const &iSlot)
SignificantEvent eventT3_
constexpr std::shared_ptr< T > & get_underlying_safe(propagate_const< std::shared_ptr< T >> &iP)
std::string const & moduleLabel() const
edm::EventID eventMaxDeltaV
void andPrint(const std::string &type, const std::string &mdlabel, const std::string &mdname) const
std::atomic< unsigned int > moduleStreamID_
char *& smapsLineBuffer()
SignificantEvent eventRssT3_
edm::propagate_const< FILE * > smapsFile_
std::map< std::string, SignificantModule > SignificantModulesMap
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
ModuleDescription const * moduleDescription() const
char const * smapsLineBuffer() const
friend struct SignificantEvent
std::ostream & operator<<(std::ostream &os, SimpleMemoryCheck::SignificantEvent const &se)
void set(double deltaV, double deltaR, edm::EventID const &e, SimpleMemoryCheck *t)
edm::propagate_const< ProcInfo * > previous_
bool monitorPssAndPrivate_
SignificantEvent eventR1_
SignificantEvent eventDeltaRssT3_
StreamID const & streamID() const
bool moduleSummaryRequested_
smapsInfo(double private_sz, double pss_sz)
bool jobReportOutputOnly_
#define DEFINE_FWK_SERVICE(type)
void updateAndPrint(const std::string &type, const std::string &mdlabel, const std::string &mdname)
bool operator==(const smapsInfo &p) const
unsigned int value() const
SignificantEvent eventR2_
void preModule(StreamContext const &, ModuleCallingContext const &)
static std::string d2str(double d)
void add(std::string const &label, ParameterSetDescription const &psetDescription)
void updateModuleMemoryStats(SignificantModule &m, double dv, edm::EventID const &)
std::atomic< int > count_
std::string error_message() const
SignificantEvent eventL2_
SignificantEvent eventDeltaRssT2_
void postEvent(StreamContext const &)
std::string mallOutput(std::string title, size_t const &n) const
edm::propagate_const< char * > smapsLineBuffer_
void watchPostModuleBeginJob(PostModuleBeginJob::slot_type const &iSlot)
void adjustMallocParams()
void postSourceConstruction(const ModuleDescription &)
Log< level::System, true > LogAbsolute
SignificantEvent eventT2_
void postSourceEvent(StreamID)
EventID const & eventID() const
void postModuleBeginJob(const ModuleDescription &)
double averageGrowthRate(double current, double past, int count)
Log< level::Warning, false > LogWarning
void set_top_pad(opt_type top_pad)
SimpleMemoryCheck(const ParameterSet &, ActivityRegistry &)
SignificantModulesMap modules_
SignificantEvent eventRssT1_
void postModule(StreamContext const &, ModuleCallingContext const &)
void postModuleConstruction(const ModuleDescription &)
bool operator>(const smapsInfo &p) const
bool monitorPssAndPrivate
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
MallocOptionSetter & getGlobalOptionSetter()
void watchPostBeginJob(PostBeginJob::slot_type const &iSlot)
convenience function for attaching to signal
std::atomic< unsigned int > moduleID_