diff options
author | Dmitry Vyukov <dvyukov@google.com> | 2013-01-24 09:08:03 +0000 |
---|---|---|
committer | Dmitry Vyukov <dvyukov@google.com> | 2013-01-24 09:08:03 +0000 |
commit | bdd844cb41718c27ef727a99a236191bc29a3df8 (patch) | |
tree | 5ade9022b178bd4c6b130c7a2cc9cb6085d7b56b /lib/tsan | |
parent | f0c846b8ef61a5f4bc664c463d643bb8dedc3768 (diff) |
tsan: implement malloc stats querying
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@173332 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/tsan')
-rw-r--r-- | lib/tsan/rtl/tsan_mman.cc | 42 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_mman.h | 4 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_rtl.cc | 5 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_rtl_thread.cc | 5 | ||||
-rw-r--r-- | lib/tsan/tests/unit/tsan_mman_test.cc | 39 |
5 files changed, 83 insertions, 12 deletions
diff --git a/lib/tsan/rtl/tsan_mman.cc b/lib/tsan/rtl/tsan_mman.cc index 6f8e90d62..314e20f63 100644 --- a/lib/tsan/rtl/tsan_mman.cc +++ b/lib/tsan/rtl/tsan_mman.cc @@ -38,8 +38,16 @@ void InitializeAllocator() { allocator()->Init(); } -void AlloctorThreadFinish(ThreadState *thr) { - allocator()->SwallowCache(&thr->alloc_cache); +void AllocatorThreadStart(ThreadState *thr) { + allocator()->InitCache(&thr->alloc_cache); +} + +void AllocatorThreadFinish(ThreadState *thr) { + allocator()->DestroyCache(&thr->alloc_cache); +} + +void AllocatorPrintStats() { + allocator()->PrintStats(); } static void SignalUnsafeCall(ThreadState *thr, uptr pc) { @@ -169,30 +177,44 @@ using namespace __tsan; extern "C" { uptr __tsan_get_current_allocated_bytes() { - return 0; + u64 stats[AllocatorStatCount]; + allocator()->GetStats(stats); + u64 m = stats[AllocatorStatMalloced]; + u64 f = stats[AllocatorStatFreed]; + return m >= f ? m - f : 1; } uptr __tsan_get_heap_size() { - return 1; + u64 stats[AllocatorStatCount]; + allocator()->GetStats(stats); + u64 m = stats[AllocatorStatMmapped]; + u64 f = stats[AllocatorStatUnmapped]; + return m >= f ? m - f : 1; } uptr __tsan_get_free_bytes() { - return 1; + return 0; } uptr __tsan_get_unmapped_bytes() { - return 1; + return 0; } uptr __tsan_get_estimated_allocated_size(uptr size) { return size; } -bool __tsan_get_ownership(const void *p) { - return true; +bool __tsan_get_ownership(void *p) { + return allocator()->GetBlockBegin(p) != 0; } -uptr __tsan_get_allocated_size(const void *p) { - return 0; +uptr __tsan_get_allocated_size(void *p) { + if (p == 0) + return 0; + p = allocator()->GetBlockBegin(p); + if (p == 0) + return 0; + MBlock *b = (MBlock*)allocator()->GetMetaData(p); + return b->size; } } // extern "C" diff --git a/lib/tsan/rtl/tsan_mman.h b/lib/tsan/rtl/tsan_mman.h index 5cf00eac8..dc31acd75 100644 --- a/lib/tsan/rtl/tsan_mman.h +++ b/lib/tsan/rtl/tsan_mman.h @@ -20,7 +20,9 @@ namespace __tsan { const uptr kDefaultAlignment = 16; void InitializeAllocator(); -void AlloctorThreadFinish(ThreadState *thr); +void AllocatorThreadStart(ThreadState *thr); +void AllocatorThreadFinish(ThreadState *thr); +void AllocatorPrintStats(); // For user allocations. void *user_alloc(ThreadState *thr, uptr pc, uptr sz, diff --git a/lib/tsan/rtl/tsan_rtl.cc b/lib/tsan/rtl/tsan_rtl.cc index 493ed2055..17a2e2d73 100644 --- a/lib/tsan/rtl/tsan_rtl.cc +++ b/lib/tsan/rtl/tsan_rtl.cc @@ -255,6 +255,11 @@ int Finalize(ThreadState *thr) { ctx->report_mtx.Lock(); ctx->report_mtx.Unlock(); +#ifndef TSAN_GO + if (ctx->flags.verbosity) + AllocatorPrintStats(); +#endif + ThreadFinalize(thr); if (ctx->nreported) { diff --git a/lib/tsan/rtl/tsan_rtl_thread.cc b/lib/tsan/rtl/tsan_rtl_thread.cc index 359775927..0c74d57e3 100644 --- a/lib/tsan/rtl/tsan_rtl_thread.cc +++ b/lib/tsan/rtl/tsan_rtl_thread.cc @@ -209,6 +209,9 @@ void ThreadStart(ThreadState *thr, int tid, uptr os_id) { thr->shadow_stack_pos = thr->shadow_stack; thr->shadow_stack_end = thr->shadow_stack + kInitStackSize; #endif +#ifndef TSAN_GO + AllocatorThreadStart(thr); +#endif tctx->thr = thr; thr->fast_synch_epoch = tctx->epoch0; thr->clock.set(tid, tctx->epoch0); @@ -269,7 +272,7 @@ void ThreadFinish(ThreadState *thr) { tctx->epoch1 = thr->fast_state.epoch(); #ifndef TSAN_GO - AlloctorThreadFinish(thr); + AllocatorThreadFinish(thr); #endif thr->~ThreadState(); StatAggregate(ctx->stat, thr->stat); diff --git a/lib/tsan/tests/unit/tsan_mman_test.cc b/lib/tsan/tests/unit/tsan_mman_test.cc index 1a9a88f60..988918fff 100644 --- a/lib/tsan/tests/unit/tsan_mman_test.cc +++ b/lib/tsan/tests/unit/tsan_mman_test.cc @@ -14,6 +14,16 @@ #include "tsan_rtl.h" #include "gtest/gtest.h" +extern "C" { +uptr __tsan_get_current_allocated_bytes(); +uptr __tsan_get_heap_size(); +uptr __tsan_get_free_bytes(); +uptr __tsan_get_unmapped_bytes(); +uptr __tsan_get_estimated_allocated_size(uptr size); +bool __tsan_get_ownership(void *p); +uptr __tsan_get_allocated_size(void *p); +} + namespace __tsan { TEST(Mman, Internal) { @@ -106,4 +116,33 @@ TEST(Mman, UserRealloc) { } } +TEST(Mman, Stats) { + ScopedInRtl in_rtl; + ThreadState *thr = cur_thread(); + + uptr alloc0 = __tsan_get_current_allocated_bytes(); + uptr heap0 = __tsan_get_heap_size(); + uptr free0 = __tsan_get_free_bytes(); + uptr unmapped0 = __tsan_get_unmapped_bytes(); + + EXPECT_EQ(__tsan_get_estimated_allocated_size(10), (uptr)10); + EXPECT_EQ(__tsan_get_estimated_allocated_size(20), (uptr)20); + EXPECT_EQ(__tsan_get_estimated_allocated_size(100), (uptr)100); + + char *p = (char*)user_alloc(thr, 0, 10); + EXPECT_EQ(__tsan_get_ownership(p), true); + EXPECT_EQ(__tsan_get_allocated_size(p), (uptr)10); + + EXPECT_EQ(__tsan_get_current_allocated_bytes(), alloc0 + 16); + EXPECT_GE(__tsan_get_heap_size(), heap0); + EXPECT_EQ(__tsan_get_free_bytes(), free0); + EXPECT_EQ(__tsan_get_unmapped_bytes(), unmapped0); + + user_free(thr, 0, p); + + EXPECT_EQ(__tsan_get_current_allocated_bytes(), alloc0); + EXPECT_GE(__tsan_get_heap_size(), heap0); + EXPECT_EQ(__tsan_get_free_bytes(), free0); + EXPECT_EQ(__tsan_get_unmapped_bytes(), unmapped0); +} } // namespace __tsan |