2121
2222#include < atomic>
2323#include < iterator>
24+ #include < utility>
2425
2526#include " absl/base/attributes.h"
2627#include " absl/base/config.h"
@@ -46,28 +47,27 @@ ABSL_CONST_INIT BorrowedFixupBuffer::FixupStackBuffer
4647
4748BorrowedFixupBuffer::~BorrowedFixupBuffer () {
4849 if (borrowed_) {
49- Unlock ();
50+ std::move (* this ). Unlock ();
5051 } else {
5152 base_internal::LowLevelAlloc::Free (frames_);
5253 }
5354}
5455
55- BorrowedFixupBuffer::BorrowedFixupBuffer (size_t length) {
56- FixupStackBuffer* fixup_buffer =
57- 0 < length && length <= FixupStackBuffer::kMaxStackElements ? TryLock ()
58- : nullptr ;
59- borrowed_ = fixup_buffer != nullptr ;
56+ BorrowedFixupBuffer::BorrowedFixupBuffer (size_t length)
57+ : borrowed_(0 < length && length <= FixupStackBuffer::kMaxStackElements
58+ ? TryLock()
59+ : nullptr ) {
6060 if (borrowed_) {
61- InitViaBorrow (fixup_buffer );
61+ InitViaBorrow ();
6262 } else {
6363 InitViaAllocation (length);
6464 }
6565}
6666
67- void BorrowedFixupBuffer::InitViaBorrow (FixupStackBuffer* borrowed_buffer ) {
67+ void BorrowedFixupBuffer::InitViaBorrow () {
6868 assert (borrowed_);
69- frames_ = borrowed_buffer ->frames ;
70- sizes_ = borrowed_buffer ->sizes ;
69+ frames_ = borrowed_ ->frames ;
70+ sizes_ = borrowed_ ->sizes ;
7171}
7272
7373void BorrowedFixupBuffer::InitViaAllocation (size_t length) {
@@ -92,25 +92,25 @@ void BorrowedFixupBuffer::InitViaAllocation(size_t length) {
9292 length * sizeof (*frames_))) int [length];
9393}
9494
95- BorrowedFixupBuffer::FixupStackBuffer* BorrowedFixupBuffer::Find () {
96- size_t i = absl::Hash<const void *>()(this ) %
97- std::size (FixupStackBuffer::g_instances);
98- return &FixupStackBuffer::g_instances[i];
99- }
100-
10195[[nodiscard]] BorrowedFixupBuffer::FixupStackBuffer*
10296BorrowedFixupBuffer::TryLock () {
103- FixupStackBuffer* instance = Find ();
104- // Use memory_order_acquire to ensure that no reads and writes on the borrowed
105- // buffer are reordered before the borrowing.
106- return !instance->in_use .test_and_set (std::memory_order_acquire) ? instance
107- : nullptr ;
97+ constexpr size_t kNumSlots = std::size (FixupStackBuffer::g_instances);
98+ const size_t i = absl::Hash<const void *>()(this ) % kNumSlots ;
99+ for (size_t k = 0 ; k < kNumSlots ; ++k) {
100+ auto * instance = &FixupStackBuffer::g_instances[(i + k) % kNumSlots ];
101+ // Use memory_order_acquire to ensure that no reads and writes on the
102+ // borrowed buffer are reordered before the borrowing.
103+ if (!instance->in_use .test_and_set (std::memory_order_acquire)) {
104+ return instance;
105+ }
106+ }
107+ return nullptr ;
108108}
109109
110- void BorrowedFixupBuffer::Unlock () {
110+ void BorrowedFixupBuffer::Unlock () && {
111111 // Use memory_order_release to ensure that no reads and writes on the borrowed
112112 // buffer are reordered after the borrowing.
113- Find () ->in_use .clear (std::memory_order_release);
113+ borrowed_ ->in_use .clear (std::memory_order_release);
114114}
115115
116116} // namespace internal_stacktrace
0 commit comments