Skip to content

Commit 937cb96

Browse files
authored
Remap thread id to avoid bitmap contention (#229)
* Remap thread id to avoid bitmap contention * Add missing file
1 parent d08dfea commit 937cb96

File tree

3 files changed

+43
-2
lines changed

3 files changed

+43
-2
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//
2+
// Borrow the implementation from openjdk
3+
// https://github.com/openjdk/jdk/blob/master/src/hotspot/share/utilities/reverse_bits.hpp
4+
//
5+
6+
#ifndef REVERSE_BITS_H
7+
#define REVERSE_BITS_H
8+
#include "arch_dd.h"
9+
#include <stdint.h>
10+
11+
static constexpr u32 rep_5555 = static_cast<u32>(UINT64_C(0x5555555555555555));
12+
static constexpr u32 rep_3333 = static_cast<u32>(UINT64_C(0x3333333333333333));
13+
static constexpr u32 rep_0F0F = static_cast<u32>(UINT64_C(0x0F0F0F0F0F0F0F0F));
14+
15+
inline u16 reverse16(u16 v) {
16+
u32 x = static_cast<u32>(v);
17+
x = ((x & rep_5555) << 1) | ((x >> 1) & rep_5555);
18+
x = ((x & rep_3333) << 2) | ((x >> 2) & rep_3333);
19+
x = ((x & rep_0F0F) << 4) | ((x >> 4) & rep_0F0F);
20+
return __builtin_bswap16(static_cast<u16>(x));
21+
}
22+
23+
#endif //REVERSE_BITS_H

ddprof-lib/src/main/cpp/threadFilter.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "threadFilter.h"
1818
#include "counters.h"
1919
#include "os.h"
20+
#include "reverse_bits.h"
2021
#include <stdlib.h>
2122
#include <string.h>
2223

@@ -85,12 +86,24 @@ void ThreadFilter::clear() {
8586
_size = 0;
8687
}
8788

89+
// The mapping has to be reversible: f(f(x)) == x
90+
int ThreadFilter::mapThreadId(int thread_id) {
91+
// We want to map the thread_id inside the same bitmap
92+
static_assert(BITMAP_SIZE >= (u16)0xffff, "Potential verflow");
93+
u16 lower16 = (u16)(thread_id & 0xffff);
94+
lower16 = reverse16(lower16);
95+
int tid = (thread_id & ~0xffff) | lower16;
96+
return tid;
97+
}
98+
8899
bool ThreadFilter::accept(int thread_id) {
100+
thread_id = mapThreadId(thread_id);
89101
u64 *b = bitmap(thread_id);
90102
return b != NULL && (word(b, thread_id) & (1ULL << (thread_id & 0x3f)));
91103
}
92104

93105
void ThreadFilter::add(int thread_id) {
106+
thread_id = mapThreadId(thread_id);
94107
u64 *b = bitmap(thread_id);
95108
if (b == NULL) {
96109
b = (u64 *)OS::safeAlloc(BITMAP_SIZE);
@@ -111,6 +124,7 @@ void ThreadFilter::add(int thread_id) {
111124
}
112125

113126
void ThreadFilter::remove(int thread_id) {
127+
thread_id = mapThreadId(thread_id);
114128
u64 *b = bitmap(thread_id);
115129
if (b == NULL) {
116130
return;
@@ -132,7 +146,10 @@ void ThreadFilter::collect(std::vector<int> &v) {
132146
// order here
133147
u64 word = __atomic_load_n(&b[j], __ATOMIC_ACQUIRE);
134148
while (word != 0) {
135-
v.push_back(start_id + j * 64 + __builtin_ctzl(word));
149+
int tid = start_id + j * 64 + __builtin_ctzl(word);
150+
// restore thread id
151+
tid = mapThreadId(tid);
152+
v.push_back(tid);
136153
word &= (word - 1);
137154
}
138155
}

ddprof-lib/src/main/cpp/threadFilter.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,12 @@ class ThreadFilter {
4545
__ATOMIC_ACQUIRE);
4646
}
4747

48+
static int mapThreadId(int thread_id);
49+
4850
u64 &word(u64 *bitmap, int thread_id) {
4951
// todo: add thread safe APIs
5052
return bitmap[((u32)thread_id % BITMAP_CAPACITY) >> 6];
5153
}
52-
5354
public:
5455
ThreadFilter();
5556
ThreadFilter(ThreadFilter &threadFilter) = delete;

0 commit comments

Comments
 (0)