Skip to content

Commit 13ef626

Browse files
authored
Merge pull request #80021 from mikeash/metadata-allocator-memory-order-tsan
[Runtime] Fix memory ordering and TSan compatibility in MetadataAllocator.
2 parents b32a1ca + 7a50a8f commit 13ef626

File tree

1 file changed

+20
-1
lines changed

1 file changed

+20
-1
lines changed

stdlib/public/runtime/Metadata.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include "swift/Runtime/Portability.h"
4242
#include "swift/Strings.h"
4343
#include "swift/Threading/Mutex.h"
44+
#include "swift/Threading/ThreadSanitizer.h"
4445
#include "llvm/ADT/StringExtras.h"
4546
#include <algorithm>
4647
#include <cctype>
@@ -7977,10 +7978,28 @@ void *MetadataAllocator::Allocate(size_t size, size_t alignment) {
79777978
Tag);
79787979
}
79797980

7981+
// If we allocated a new page, then we need to do a store-release to ensure
7982+
// the initialization writes are properly ordered when viewed from other
7983+
// threads that read from the new page. If we did not allocate a new page,
7984+
// then we need a load-consume to cover the other side of that.
7985+
std::memory_order successOrder = allocatedNewPage
7986+
? std::memory_order_release
7987+
: SWIFT_MEMORY_ORDER_CONSUME;
7988+
79807989
// Swap in the new state.
79817990
if (AllocationPool.compare_exchange_weak(curState, newState,
7982-
std::memory_order_relaxed,
7991+
successOrder,
79837992
std::memory_order_relaxed)) {
7993+
// If the program is using Thread Sanitizer, it can't see our memory
7994+
// ordering, so inform it manually. TSan will track the consume ordering
7995+
// in __swift_instantiateConcreteTypeFromMangledName so we register the
7996+
// correct ordering with threads that get a metadata pointer from a cache
7997+
// variable too.
7998+
if (allocatedNewPage)
7999+
swift::tsan::release(&AllocationPool);
8000+
else
8001+
swift::tsan::acquire(&AllocationPool);
8002+
79848003
// If that succeeded, we've successfully allocated.
79858004
__msan_allocated_memory(allocation, sizeWithHeader);
79868005
__asan_unpoison_memory_region(allocation, sizeWithHeader);

0 commit comments

Comments
 (0)