Skip to content

Commit ddbd544

Browse files
authored
Merge pull request #46542 from makortel/pluginManagerExcludeMaxMemoryPreload
Exclude PluginManager cache from MaxMemoryPreload monitoring
2 parents 80c43fa + b121ddf commit ddbd544

File tree

5 files changed

+74
-0
lines changed

5 files changed

+74
-0
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#include "PauseMaxMemoryPreloadSentry.h"
2+
3+
// By default do nothing, but add "hooks" that MaxMemoryPreload can
4+
// override with LD_PRELOAD
5+
void pauseMaxMemoryPreload() {}
6+
void unpauseMaxMemoryPreload() {}
7+
8+
namespace edm {
9+
PauseMaxMemoryPreloadSentry::PauseMaxMemoryPreloadSentry() { pauseMaxMemoryPreload(); }
10+
PauseMaxMemoryPreloadSentry::~PauseMaxMemoryPreloadSentry() { unpauseMaxMemoryPreload(); }
11+
} // namespace edm
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#ifndef FWCore_PluginManager_src_PauseMaxMemoryPreloadSentry_h
2+
#define FWCore_PluginManager_src_PauseMaxMemoryPreloadSentry_h
3+
4+
namespace edm {
5+
class PauseMaxMemoryPreloadSentry {
6+
public:
7+
PauseMaxMemoryPreloadSentry();
8+
~PauseMaxMemoryPreloadSentry();
9+
10+
PauseMaxMemoryPreloadSentry(const PauseMaxMemoryPreloadSentry&) = delete;
11+
PauseMaxMemoryPreloadSentry(PauseMaxMemoryPreloadSentry&&) = delete;
12+
PauseMaxMemoryPreloadSentry& operator=(const PauseMaxMemoryPreloadSentry&) = delete;
13+
PauseMaxMemoryPreloadSentry& operator=(PauseMaxMemoryPreloadSentry&&) = delete;
14+
};
15+
} // namespace edm
16+
17+
#endif

FWCore/PluginManager/src/PluginManager.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
#include "FWCore/Utilities/interface/Exception.h"
3030
#include "FWCore/Utilities/interface/thread_safety_macros.h"
3131

32+
#include "PauseMaxMemoryPreloadSentry.h"
33+
3234
namespace edmplugin {
3335
//
3436
// constants, enums and typedefs
@@ -47,6 +49,7 @@ namespace edmplugin {
4749
throw cms::Exception("PluginMangerCacheProblem")
4850
<< "Unable to open the cache file '" << cacheFile.string() << "'. Please check permissions on file";
4951
}
52+
edm::PauseMaxMemoryPreloadSentry pauseSentry;
5053
CacheParser::read(file, dir, categoryToInfos);
5154
return true;
5255
}

PerfTools/MaxMemoryPreload/README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,33 @@ LD_PRELOAD="libPerfToolsAllocMonitorPreload.so libPerfToolsMaxMemoryPreload.so"
1616

1717
the order is important.
1818

19+
### Pausing the monitoring
20+
21+
It is possible to temporarily pause the monitoring by instrumenting the target application by definining the following functions
22+
```cpp
23+
// in some header,
24+
void pauseMaxMemoryPreload();
25+
void unpauseMaxMemoryPreload();
26+
27+
// in an implementation source file
28+
void pauseMaxMemoryPreload() {
29+
}
30+
void unpauseMaxMemoryPreload() {
31+
}
32+
```
33+
and then using these in code
34+
```cpp
35+
...
36+
pauseMaxMemoryPreload();
37+
// code that should be excluded from the monitoring
38+
unpauseMaxMemoryPreload();
39+
...
40+
```
41+
42+
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`.
43+
44+
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.
45+
1946
## Reporting
2047
When the application ends, the monitor will report the following to standard error:
2148

PerfTools/MaxMemoryPreload/src/preload.cc

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,16 @@
2626
// static data member definitions
2727
//
2828

29+
// Hooks the target application can be instrumented with to pause and
30+
// unpause the MaxMemoryPreload. Pausing the monitoring during a
31+
// multithreaded execution can result in unexpected results, because
32+
// the setting is global.
33+
namespace {
34+
std::atomic<bool> paused = false;
35+
}
36+
void pauseMaxMemoryPreload() { paused = true; }
37+
void unpauseMaxMemoryPreload() { paused = false; }
38+
2939
namespace {
3040
class MonitorAdaptor : public cms::perftools::AllocMonitorBase {
3141
public:
@@ -34,6 +44,9 @@ namespace {
3444

3545
private:
3646
void allocCalled(size_t iRequested, size_t iActual, void const*) final {
47+
if (paused)
48+
return;
49+
3750
nAllocations_.fetch_add(1, std::memory_order_acq_rel);
3851
requested_.fetch_add(iRequested, std::memory_order_acq_rel);
3952

@@ -48,6 +61,9 @@ namespace {
4861
}
4962
}
5063
void deallocCalled(size_t iActual, void const*) final {
64+
if (paused)
65+
return;
66+
5167
nDeallocations_.fetch_add(1, std::memory_order_acq_rel);
5268
auto present = presentActual_.load(std::memory_order_acquire);
5369
if (present >= iActual) {

0 commit comments

Comments
 (0)