summaryrefslogtreecommitdiff
path: root/lib/esan/working_set.cpp
diff options
context:
space:
mode:
authorDerek Bruening <bruening@google.com>2016-06-03 16:14:07 +0000
committerDerek Bruening <bruening@google.com>2016-06-03 16:14:07 +0000
commitd5bcae95c1d1b013893bd3ca6cc04e7f7f5d5736 (patch)
tree97124f984e3e8aa833e4960444193770683a4730 /lib/esan/working_set.cpp
parent031c1e40660c8eaaa418ce84b16b82b37ca32652 (diff)
[esan] Add sideline itimer support
Summary: Adds support for creating a separate thread for performing "sideline" actions on a periodic basis via an itimer. A new class SidelineThread implements this feature, exposing a sampling callback to the caller. Adds initial usage of sideline sampling to the working set tool. For now it simply prints the usage at each snapshot at verbosity level 1. Adds a test of this behavior. Adds a new option -record_snapshots to control whether we sample and a new option -sample_freq to control the periodicity of the sampling. Reviewers: aizatsky Subscribers: vitalybuka, zhaoqin, kcc, eugenis, llvm-commits, kubabrecka Differential Revision: http://reviews.llvm.org/D20751 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@271682 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/esan/working_set.cpp')
-rw-r--r--lib/esan/working_set.cpp23
1 files changed, 23 insertions, 0 deletions
diff --git a/lib/esan/working_set.cpp b/lib/esan/working_set.cpp
index dcd683737..f4ed8a17e 100644
--- a/lib/esan/working_set.cpp
+++ b/lib/esan/working_set.cpp
@@ -16,6 +16,7 @@
#include "esan.h"
#include "esan_flags.h"
#include "esan_shadow.h"
+#include "esan_sideline.h"
#include "sanitizer_common/sanitizer_procmaps.h"
// We shadow every cache line of app memory with one shadow byte.
@@ -40,6 +41,12 @@ static const u32 CurWorkingSetBitIdx = 0;
static const byte ShadowAccessedVal =
(1 << TotalWorkingSetBitIdx) | (1 << CurWorkingSetBitIdx);
+static SidelineThread Thread;
+// If we use real-time-based timer samples this won't overflow in any realistic
+// scenario, but if we switch to some other unit (such as memory accesses) we
+// may want to consider a 64-bit int.
+static u32 SnapshotNum;
+
void processRangeAccessWorkingSet(uptr PC, uptr Addr, SIZE_T Size,
bool IsWrite) {
if (Size == 0)
@@ -124,9 +131,22 @@ static u32 computeWorkingSizeAndReset(u32 BitIdx) {
return WorkingSetSize;
}
+// This is invoked from a signal handler but in a sideline thread doing nothing
+// else so it is a little less fragile than a typical signal handler.
+static void takeSample(void *Arg) {
+ // FIXME: record the size and report at process end. For now this simply
+ // serves as a test of the sideline thread functionality.
+ VReport(1, "%s: snapshot #%d: %u\n", SanitizerToolName, SnapshotNum,
+ computeWorkingSizeAndReset(CurWorkingSetBitIdx));
+ ++SnapshotNum;
+}
+
void initializeWorkingSet() {
CHECK(getFlags()->cache_line_size == CacheLineSize);
registerMemoryFaultHandler();
+
+ if (getFlags()->record_snapshots)
+ Thread.launchThread(takeSample, nullptr, getFlags()->sample_freq);
}
static u32 getSizeForPrinting(u32 NumOfCachelines, const char *&Unit) {
@@ -147,6 +167,9 @@ static u32 getSizeForPrinting(u32 NumOfCachelines, const char *&Unit) {
}
int finalizeWorkingSet() {
+ if (getFlags()->record_snapshots)
+ Thread.joinThread();
+
// Get the working set size for the entire execution.
u32 NumOfCachelines = computeWorkingSizeAndReset(TotalWorkingSetBitIdx);
const char *Unit;