Skip to content

Commit

Permalink
Merge pull request #46542 from makortel/pluginManagerExcludeMaxMemory…
Browse files Browse the repository at this point in the history
…Preload

Exclude PluginManager cache from MaxMemoryPreload monitoring
  • Loading branch information
cmsbuild authored Nov 8, 2024
2 parents 80c43fa + b121ddf commit ddbd544
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 0 deletions.
11 changes: 11 additions & 0 deletions FWCore/PluginManager/src/PauseMaxMemoryPreloadSentry.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include "PauseMaxMemoryPreloadSentry.h"

// By default do nothing, but add "hooks" that MaxMemoryPreload can
// override with LD_PRELOAD
void pauseMaxMemoryPreload() {}
void unpauseMaxMemoryPreload() {}

namespace edm {
PauseMaxMemoryPreloadSentry::PauseMaxMemoryPreloadSentry() { pauseMaxMemoryPreload(); }
PauseMaxMemoryPreloadSentry::~PauseMaxMemoryPreloadSentry() { unpauseMaxMemoryPreload(); }
} // namespace edm
17 changes: 17 additions & 0 deletions FWCore/PluginManager/src/PauseMaxMemoryPreloadSentry.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#ifndef FWCore_PluginManager_src_PauseMaxMemoryPreloadSentry_h
#define FWCore_PluginManager_src_PauseMaxMemoryPreloadSentry_h

namespace edm {
class PauseMaxMemoryPreloadSentry {
public:
PauseMaxMemoryPreloadSentry();
~PauseMaxMemoryPreloadSentry();

PauseMaxMemoryPreloadSentry(const PauseMaxMemoryPreloadSentry&) = delete;
PauseMaxMemoryPreloadSentry(PauseMaxMemoryPreloadSentry&&) = delete;
PauseMaxMemoryPreloadSentry& operator=(const PauseMaxMemoryPreloadSentry&) = delete;
PauseMaxMemoryPreloadSentry& operator=(PauseMaxMemoryPreloadSentry&&) = delete;
};
} // namespace edm

#endif
3 changes: 3 additions & 0 deletions FWCore/PluginManager/src/PluginManager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
#include "FWCore/Utilities/interface/Exception.h"
#include "FWCore/Utilities/interface/thread_safety_macros.h"

#include "PauseMaxMemoryPreloadSentry.h"

namespace edmplugin {
//
// constants, enums and typedefs
Expand All @@ -47,6 +49,7 @@ namespace edmplugin {
throw cms::Exception("PluginMangerCacheProblem")
<< "Unable to open the cache file '" << cacheFile.string() << "'. Please check permissions on file";
}
edm::PauseMaxMemoryPreloadSentry pauseSentry;
CacheParser::read(file, dir, categoryToInfos);
return true;
}
Expand Down
27 changes: 27 additions & 0 deletions PerfTools/MaxMemoryPreload/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,33 @@ LD_PRELOAD="libPerfToolsAllocMonitorPreload.so libPerfToolsMaxMemoryPreload.so"

the order is important.

### Pausing the monitoring

It is possible to temporarily pause the monitoring by instrumenting the target application by definining the following functions
```cpp
// in some header,
void pauseMaxMemoryPreload();
void unpauseMaxMemoryPreload();

// in an implementation source file
void pauseMaxMemoryPreload() {
}
void unpauseMaxMemoryPreload() {
}
```
and then using these in code
```cpp
...
pauseMaxMemoryPreload();
// code that should be excluded from the monitoring
unpauseMaxMemoryPreload();
...
```

The trick is that by default these functions are defined in the application, and the functions do nothing. The `libPerfToolsMaxMemoryPreload.so` provides also the same functions that actually pause the data collection, and the LD_PRELOADing makes the application to call the functions within `libPerfToolsMaxMemoryPreload.so`.

It is recommended to not pause the monitoring within a multithreaded section, because that could result in unexpected results, because the pausing setting is global.

## Reporting
When the application ends, the monitor will report the following to standard error:

Expand Down
16 changes: 16 additions & 0 deletions PerfTools/MaxMemoryPreload/src/preload.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@
// static data member definitions
//

// Hooks the target application can be instrumented with to pause and
// unpause the MaxMemoryPreload. Pausing the monitoring during a
// multithreaded execution can result in unexpected results, because
// the setting is global.
namespace {
std::atomic<bool> paused = false;
}
void pauseMaxMemoryPreload() { paused = true; }
void unpauseMaxMemoryPreload() { paused = false; }

namespace {
class MonitorAdaptor : public cms::perftools::AllocMonitorBase {
public:
Expand All @@ -34,6 +44,9 @@ namespace {

private:
void allocCalled(size_t iRequested, size_t iActual, void const*) final {
if (paused)
return;

nAllocations_.fetch_add(1, std::memory_order_acq_rel);
requested_.fetch_add(iRequested, std::memory_order_acq_rel);

Expand All @@ -48,6 +61,9 @@ namespace {
}
}
void deallocCalled(size_t iActual, void const*) final {
if (paused)
return;

nDeallocations_.fetch_add(1, std::memory_order_acq_rel);
auto present = presentActual_.load(std::memory_order_acquire);
if (present >= iActual) {
Expand Down

0 comments on commit ddbd544

Please sign in to comment.