Skip to content

Remap thread id to avoid bitmap contention #223

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions ddprof-lib/src/main/cpp/reverse_bits.h
Original file line number Diff line number Diff line change
@@ -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 <stdint.h>

static constexpr u32 rep_5555 = static_cast<u32>(UINT64_C(0x5555555555555555));
static constexpr u32 rep_3333 = static_cast<u32>(UINT64_C(0x3333333333333333));
static constexpr u32 rep_0F0F = static_cast<u32>(UINT64_C(0x0F0F0F0F0F0F0F0F));

inline u16 reverse16(u16 v) {
u32 x = static_cast<u32>(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<u16>(x));
}

#endif //REVERSE_BITS_H
19 changes: 18 additions & 1 deletion ddprof-lib/src/main/cpp/threadFilter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "threadFilter.h"
#include "counters.h"
#include "os.h"
#include "reverse_bits.h"
#include <stdlib.h>
#include <string.h>

Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand All @@ -132,7 +146,10 @@ void ThreadFilter::collect(std::vector<int> &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);
}
}
Expand Down
3 changes: 2 additions & 1 deletion ddprof-lib/src/main/cpp/threadFilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Loading