From ce7f502294bc28e87b7ce46cba6380f10f10cd5f Mon Sep 17 00:00:00 2001 From: Zhengyu Gu Date: Tue, 17 Jun 2025 16:28:44 -0400 Subject: [PATCH 1/2] Remap thread id to avoid bitmap contention --- ddprof-lib/src/main/cpp/threadFilter.cpp | 19 ++++++++++++++++++- ddprof-lib/src/main/cpp/threadFilter.h | 3 ++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/ddprof-lib/src/main/cpp/threadFilter.cpp b/ddprof-lib/src/main/cpp/threadFilter.cpp index 034aabf9b..1e73a955c 100644 --- a/ddprof-lib/src/main/cpp/threadFilter.cpp +++ b/ddprof-lib/src/main/cpp/threadFilter.cpp @@ -17,6 +17,7 @@ #include "threadFilter.h" #include "counters.h" #include "os.h" +#include "reverse_bits.h" #include #include @@ -85,12 +86,24 @@ void ThreadFilter::clear() { _size = 0; } +// The mapping has to be reversible: f(f(x)) == x +int ThreadFilter::mapThreadId(int thread_id) { + // We want to map the thread_id inside the same bitmap + static_assert(BITMAP_SIZE >= (u16)0xffff, "Potential verflow"); + u16 lower16 = (u16)(thread_id & 0xffff); + lower16 = reverse16(lower16); + int tid = (thread_id & ~0xffff) | lower16; + return tid; +} + bool ThreadFilter::accept(int thread_id) { + thread_id = mapThreadId(thread_id); u64 *b = bitmap(thread_id); return b != NULL && (word(b, thread_id) & (1ULL << (thread_id & 0x3f))); } void ThreadFilter::add(int thread_id) { + thread_id = mapThreadId(thread_id); u64 *b = bitmap(thread_id); if (b == NULL) { b = (u64 *)OS::safeAlloc(BITMAP_SIZE); @@ -111,6 +124,7 @@ void ThreadFilter::add(int thread_id) { } void ThreadFilter::remove(int thread_id) { + thread_id = mapThreadId(thread_id); u64 *b = bitmap(thread_id); if (b == NULL) { return; @@ -132,7 +146,10 @@ void ThreadFilter::collect(std::vector &v) { // order here u64 word = __atomic_load_n(&b[j], __ATOMIC_ACQUIRE); while (word != 0) { - v.push_back(start_id + j * 64 + __builtin_ctzl(word)); + int tid = start_id + j * 64 + __builtin_ctzl(word); + // restore thread id + tid = mapThreadId(tid); + v.push_back(tid); word &= (word - 1); } } diff --git a/ddprof-lib/src/main/cpp/threadFilter.h b/ddprof-lib/src/main/cpp/threadFilter.h index cec7e7048..0247f51e6 100644 --- a/ddprof-lib/src/main/cpp/threadFilter.h +++ b/ddprof-lib/src/main/cpp/threadFilter.h @@ -45,11 +45,12 @@ class ThreadFilter { __ATOMIC_ACQUIRE); } + static int mapThreadId(int thread_id); + u64 &word(u64 *bitmap, int thread_id) { // todo: add thread safe APIs return bitmap[((u32)thread_id % BITMAP_CAPACITY) >> 6]; } - public: ThreadFilter(); ThreadFilter(ThreadFilter &threadFilter) = delete; From 77b28ef06f8c9b40f9eae012355a74442c71689e Mon Sep 17 00:00:00 2001 From: Zhengyu Gu Date: Tue, 17 Jun 2025 16:33:43 -0400 Subject: [PATCH 2/2] Add missing file --- ddprof-lib/src/main/cpp/reverse_bits.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 ddprof-lib/src/main/cpp/reverse_bits.h diff --git a/ddprof-lib/src/main/cpp/reverse_bits.h b/ddprof-lib/src/main/cpp/reverse_bits.h new file mode 100644 index 000000000..81e46e19a --- /dev/null +++ b/ddprof-lib/src/main/cpp/reverse_bits.h @@ -0,0 +1,23 @@ +// +// Borrow the implementation from openjdk +// https://github.com/openjdk/jdk/blob/master/src/hotspot/share/utilities/reverse_bits.hpp +// + +#ifndef REVERSE_BITS_H +#define REVERSE_BITS_H +#include "arch_dd.h" +#include + +static constexpr u32 rep_5555 = static_cast(UINT64_C(0x5555555555555555)); +static constexpr u32 rep_3333 = static_cast(UINT64_C(0x3333333333333333)); +static constexpr u32 rep_0F0F = static_cast(UINT64_C(0x0F0F0F0F0F0F0F0F)); + +inline u16 reverse16(u16 v) { + u32 x = static_cast(v); + x = ((x & rep_5555) << 1) | ((x >> 1) & rep_5555); + x = ((x & rep_3333) << 2) | ((x >> 2) & rep_3333); + x = ((x & rep_0F0F) << 4) | ((x >> 4) & rep_0F0F); + return __builtin_bswap16(static_cast(x)); +} + +#endif //REVERSE_BITS_H