@@ -17,12 +17,24 @@ ThreadFilter::~ThreadFilter() {
1717 std::unique_lock<std::mutex> lock (_slot_mutex);
1818 _slots.clear ();
1919}
20-
2120ThreadFilter::SlotID ThreadFilter::registerThread () {
21+ int top = _free_list_top.load (std::memory_order_acquire);
22+ for (int i = 0 ; i < top; ++i) {
23+ int value = _free_list[i].load (std::memory_order_relaxed);
24+ if (value >= 0 ) {
25+ int expected = value;
26+ if (_free_list[i].compare_exchange_strong (expected, -1 , std::memory_order_acq_rel)) {
27+ return value; // Successfully claimed a free slot
28+ }
29+ // If CAS fails, someone else claimed it, continue scanning
30+ }
31+ }
32+
2233 SlotID index = _next_index.fetch_add (1 , std::memory_order_relaxed);
2334 if (index >= kMaxThreads ) {
2435 return -1 ;
2536 }
37+
2638 const int outer_idx = index >> kChunkShift ;
2739 {
2840 if (outer_idx < static_cast <int >(_slots.size ())) {
@@ -46,6 +58,10 @@ void ThreadFilter::clear() {
4658 slot.value .store (-1 , std::memory_order_relaxed);
4759 }
4860 }
61+ for (int i = 0 ; i < kFreeListSize ; ++i) {
62+ _free_list[i].store (-1 , std::memory_order_relaxed);
63+ }
64+ _free_list_top.store (0 , std::memory_order_relaxed);
4965}
5066
5167bool ThreadFilter::accept (SlotID slot_id) const {
@@ -73,9 +89,35 @@ void ThreadFilter::remove(SlotID slot_id) {
7389
7490void ThreadFilter::unregisterThread (SlotID slot_id) {
7591 if (slot_id < 0 ) return ;
92+
7693 int outer_idx = slot_id >> kChunkShift ;
7794 int inner_idx = slot_id & kChunkMask ;
7895 _slots[outer_idx][inner_idx].value .store (-1 , std::memory_order_relaxed);
96+
97+ constexpr int try_limit = 16 ;
98+
99+ int top = _free_list_top.load (std::memory_order_acquire);
100+ int limit = top < kFreeListSize ? top : kFreeListSize ;
101+ int tries = 0 ;
102+
103+ for (int i = 0 ; i < limit && tries < try_limit; ++i) {
104+ int value = _free_list[i].load (std::memory_order_relaxed);
105+ if (value == -1 ) {
106+ int expected = -1 ;
107+ if (_free_list[i].compare_exchange_strong (expected, slot_id, std::memory_order_acq_rel)) {
108+ return ; // Successfully claimed empty spot
109+ }
110+ ++tries; // Only count actual CAS attempts
111+ }
112+ }
113+
114+ // Fallback: append if no empty slot found
115+ int pos = _free_list_top.fetch_add (1 , std::memory_order_acq_rel);
116+ if (pos < kFreeListSize ) {
117+ _free_list[pos].store (slot_id, std::memory_order_release);
118+ } else {
119+ // Free list overflow: ignore
120+ }
79121}
80122
81123void ThreadFilter::collect (std::vector<int >& tids) const {
0 commit comments