[useful] Drop bespoke CountTrailingZeros impl (#37084)

use `absl::countr_zero` instead

Built on #37083 which should be merged first

Closes #37084

COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/37084 from ctiller:less-bespoke-3 8c30e8fdc5
PiperOrigin-RevId: 658642077
pull/37385/head
Craig Tiller 8 months ago committed by Copybara-Service
parent 848272c570
commit 21b10d8c1d
  1. 6
      src/core/lib/promise/party.cc
  2. 24
      src/core/util/useful.h
  3. 49
      test/core/util/useful_test.cc

@ -276,7 +276,7 @@ void Party::RunPartyAndUnref(uint64_t prev_state) {
auto wakeup_mask = std::exchange(wakeup_mask_, 0);
while (wakeup_mask != 0) {
const uint64_t t = LowestOneBit(wakeup_mask);
const int i = CountTrailingZeros(t);
const int i = absl::countr_zero(t);
wakeup_mask ^= t;
// If the participant is null, skip.
// This allows participants to complete whilst wakers still exist
@ -364,7 +364,7 @@ void Party::AddParticipants(Participant** participants, size_t count) {
}
wakeup_mask |= new_mask;
allocated |= new_mask;
slots[i] = CountTrailingZeros(new_mask);
slots[i] = absl::countr_zero(new_mask);
}
// Try to allocate this slot and take a ref (atomically).
// Ref needs to be taken because once we store the participant it could be
@ -406,7 +406,7 @@ void Party::AddParticipant(Participant* participant) {
<< "No available slots for new participant; allocated=" << allocated
<< " state=" << state << " wakeup_mask=" << wakeup_mask;
allocated |= wakeup_mask;
slot = CountTrailingZeros(wakeup_mask);
slot = absl::countr_zero(wakeup_mask);
// Try to allocate this slot and take a ref (atomically).
// Ref needs to be taken because once we store the participant it could be
// spuriously woken up and unref the party.

@ -57,30 +57,6 @@ bool GetBit(T i, size_t n) {
return (i & (T(1) << n)) != 0;
}
#if GRPC_HAS_BUILTIN(__builtin_ctz)
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline uint32_t CountTrailingZeros(
uint32_t i) {
DCHECK_NE(i, 0u); // __builtin_ctz returns undefined behavior for 0
return __builtin_ctz(i);
}
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline uint32_t CountTrailingZeros(
uint64_t i) {
DCHECK_NE(i, 0u); // __builtin_ctz returns undefined behavior for 0
return __builtin_ctzll(i);
}
#else
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline uint32_t CountTrailingZeros(
uint32_t i) {
DCHECK_NE(i, 0); // __builtin_ctz returns undefined behavior for 0
return absl::popcount((i & -i) - 1);
}
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline uint32_t CountTrailingZeros(
uint64_t i) {
DCHECK_NE(i, 0); // __builtin_ctz returns undefined behavior for 0
return absl::popcount((i & -i) - 1);
}
#endif
// This function uses operator< to implement a qsort-style comparison, whereby:
// if a is smaller than b, a number smaller than 0 is returned.
// if a is bigger than b, a number greater than 0 is returned.

@ -81,55 +81,6 @@ TEST(UsefulTest, RoundUpToPowerOf2) {
EXPECT_EQ(RoundUpToPowerOf2(8), 8);
}
TEST(UsefulTest, CountTrailingZeros32) {
EXPECT_EQ(CountTrailingZeros(static_cast<uint32_t>(1)), 0);
EXPECT_EQ(CountTrailingZeros(static_cast<uint32_t>(2)), 1);
EXPECT_EQ(CountTrailingZeros(static_cast<uint32_t>(3)), 0);
EXPECT_EQ(CountTrailingZeros(static_cast<uint32_t>(4)), 2);
EXPECT_EQ(CountTrailingZeros(static_cast<uint32_t>(5)), 0);
EXPECT_EQ(CountTrailingZeros(static_cast<uint32_t>(6)), 1);
EXPECT_EQ(CountTrailingZeros(static_cast<uint32_t>(7)), 0);
EXPECT_EQ(CountTrailingZeros(static_cast<uint32_t>(8)), 3);
EXPECT_EQ(CountTrailingZeros(static_cast<uint32_t>(9)), 0);
EXPECT_EQ(CountTrailingZeros(static_cast<uint32_t>(10)), 1);
EXPECT_EQ(CountTrailingZeros(static_cast<uint32_t>(11)), 0);
EXPECT_EQ(CountTrailingZeros(static_cast<uint32_t>(12)), 2);
EXPECT_EQ(CountTrailingZeros(static_cast<uint32_t>(13)), 0);
EXPECT_EQ(CountTrailingZeros(static_cast<uint32_t>(14)), 1);
EXPECT_EQ(CountTrailingZeros(static_cast<uint32_t>(15)), 0);
EXPECT_EQ(CountTrailingZeros(static_cast<uint32_t>(16)), 4);
EXPECT_EQ(CountTrailingZeros(static_cast<uint32_t>(256)), 8);
EXPECT_EQ(CountTrailingZeros(static_cast<uint32_t>(65535)), 0);
EXPECT_EQ(CountTrailingZeros(static_cast<uint32_t>(65536)), 16);
EXPECT_EQ(CountTrailingZeros(static_cast<uint32_t>(0x80000000)), 31);
}
TEST(UsefulTest, CountTrailingZeros64) {
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(1)), 0);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(2)), 1);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(3)), 0);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(4)), 2);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(5)), 0);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(6)), 1);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(7)), 0);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(8)), 3);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(9)), 0);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(10)), 1);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(11)), 0);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(12)), 2);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(13)), 0);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(14)), 1);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(15)), 0);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(16)), 4);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(256)), 8);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(65535)), 0);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(65536)), 16);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(0x80000000)), 31);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(0x100000000)), 32);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(0x1000000000000)), 48);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(0x8000000000000000)), 63);
}
TEST(UsefulTest, LowestOneBit8) {
EXPECT_EQ(LowestOneBit(static_cast<uint8_t>(0)), 0);
EXPECT_EQ(LowestOneBit(static_cast<uint8_t>(1)), 1);

Loading…
Cancel
Save