Skip to content
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

[libc++] Make sure the test for compare-and-wait bug doesn't hang forever #97907

Merged
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,40 @@

// XFAIL: availability-synchronization_library-missing

// This is a regression test for https://github.com/llvm/llvm-project/issues/85107, which describes
// how we were using UL_COMPARE_AND_WAIT instead of UL_COMPARE_AND_WAIT64 in the implementation of
// atomic::wait, leading to potential infinite hangs.

#include <atomic>
#include <cassert>
#include <chrono>

#include "make_test_thread.h"

void test_85107() {
int main(int, char**) {
if constexpr (sizeof(std::__cxx_contention_t) == 8 && sizeof(long) > 4) {
std::atomic<bool> done = false;
auto const timeout = std::chrono::system_clock::now() + std::chrono::seconds(600); // fail after 10 minutes

auto timeout_thread = support::make_test_thread([&] {
while (!done) {
assert(std::chrono::system_clock::now() < timeout); // make sure we don't hang forever
}
});

// https://github.com/llvm/llvm-project/issues/85107
// [libc++] atomic_wait uses UL_COMPARE_AND_WAIT when it should use UL_COMPARE_AND_WAIT64 on Darwin
constexpr std::__cxx_contention_t old_val = 0;
constexpr std::__cxx_contention_t new_val = old_val + (1ll << 32);
std::__cxx_atomic_contention_t ct(new_val);
std::__libcpp_atomic_wait(&ct, old_val); // this will hang forever if the bug is present
}
}

int main(int, char**) {
test_85107();
// This would hang forever if the bug is present, but the test will fail in a bounded amount of
// time due to the timeout above.
std::__libcpp_atomic_wait(&ct, old_val);

done = true;
timeout_thread.join();
}

return 0;
}
Loading