[compiler-rt] [scudo] Add EnableMultiRegions mode (PR #98076)
Christopher Ferris via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 16 17:40:07 PST 2024
================
@@ -155,82 +176,111 @@ template <typename Config> class SizeClassAllocator64 {
void unmapTestOnly() {
for (uptr I = 0; I < NumClasses; I++) {
- RegionInfo *Region = getRegionInfo(I);
- {
- ScopedLock ML(Region->MMLock);
- MemMapT MemMap = Region->MemMapInfo.MemMap;
+ auto RegionInfoIter = RegionInfoManager.getRegionInfoIter(I);
+ do {
+ ScopedLock ML(RegionInfoIter->MMLock);
+ MemMapT MemMap = RegionInfoIter->MemMapInfo.MemMap;
if (MemMap.isAllocated())
MemMap.unmap(MemMap.getBase(), MemMap.getCapacity());
- }
- *Region = {};
+ RegionInfo *OldRegion = RegionInfoIter.get();
+ ++RegionInfoIter;
+ *OldRegion = {};
+ } while (!RegionInfoIter.end());
}
}
// When all blocks are freed, it has to be the same size as `AllocatedUser`.
void verifyAllBlocksAreReleasedTestOnly() {
+ uptr NumRegionInfo = 0;
+ // TODO: Verify all pointers are belong to the right region
// `BatchGroup` and `TransferBatch` also use the blocks from BatchClass.
uptr BatchClassUsedInFreeLists = 0;
for (uptr I = 0; I < NumClasses; I++) {
// We have to count BatchClassUsedInFreeLists in other regions first.
if (I == SizeClassMap::BatchClassId)
continue;
- RegionInfo *Region = getRegionInfo(I);
- ScopedLock ML(Region->MMLock);
- ScopedLock FL(Region->FLLock);
- const uptr BlockSize = getSizeByClassId(I);
- uptr TotalBlocks = 0;
- for (BatchGroupT &BG : Region->FreeListInfo.BlockList) {
- // `BG::Batches` are `TransferBatches`. +1 for `BatchGroup`.
- BatchClassUsedInFreeLists += BG.Batches.size() + 1;
- for (const auto &It : BG.Batches)
- TotalBlocks += It.getCount();
- }
+ auto RegionInfoIter = RegionInfoManager.getRegionInfoIter(I);
+
+ do {
+ ++NumRegionInfo;
+
+ ScopedLock ML(RegionInfoIter->MMLock);
+ ScopedLock FL(RegionInfoIter->FLLock);
+ const uptr BlockSize = getSizeByClassId(I);
+ uptr TotalBlocks = 0;
+ for (BatchGroupT &BG : RegionInfoIter->FreeListInfo.BlockList) {
+ // `BG::Batches` are `TransferBatches`. +1 for `BatchGroup`.
+ BatchClassUsedInFreeLists += BG.Batches.size() + 1;
+ for (const auto &It : BG.Batches)
+ TotalBlocks += It.getCount();
+ }
- DCHECK_EQ(TotalBlocks, Region->MemMapInfo.AllocatedUser / BlockSize);
- DCHECK_EQ(Region->FreeListInfo.PushedBlocks,
- Region->FreeListInfo.PoppedBlocks);
+ DCHECK_EQ(TotalBlocks,
+ RegionInfoIter->MemMapInfo.AllocatedUser / BlockSize);
+ DCHECK_EQ(RegionInfoIter->FreeListInfo.PushedBlocks,
+ RegionInfoIter->FreeListInfo.PoppedBlocks);
+
+ ++RegionInfoIter;
+ } while (!RegionInfoIter.end());
}
- RegionInfo *Region = getRegionInfo(SizeClassMap::BatchClassId);
- ScopedLock ML(Region->MMLock);
- ScopedLock FL(Region->FLLock);
- const uptr BlockSize = getSizeByClassId(SizeClassMap::BatchClassId);
- uptr TotalBlocks = 0;
- for (BatchGroupT &BG : Region->FreeListInfo.BlockList) {
- if (LIKELY(!BG.Batches.empty())) {
- for (const auto &It : BG.Batches)
- TotalBlocks += It.getCount();
- } else {
- // `BatchGroup` with empty freelist doesn't have `TransferBatch` record
- // itself.
- ++TotalBlocks;
+ auto RegionInfoIter =
+ RegionInfoManager.getRegionInfoIter(SizeClassMap::BatchClassId);
+
+ do {
+ ++NumRegionInfo;
+
+ ScopedLock ML(RegionInfoIter->MMLock);
+ ScopedLock FL(RegionInfoIter->FLLock);
+ const uptr BlockSize = getSizeByClassId(SizeClassMap::BatchClassId);
+ uptr TotalBlocks = 0;
+ for (BatchGroupT &BG : RegionInfoIter->FreeListInfo.BlockList) {
+ if (LIKELY(!BG.Batches.empty())) {
+ for (const auto &It : BG.Batches)
+ TotalBlocks += It.getCount();
+ } else {
+ // `BatchGroup` with empty freelist doesn't have `TransferBatch`
+ // record itself.
+ ++TotalBlocks;
+ }
}
- }
- DCHECK_EQ(TotalBlocks + BatchClassUsedInFreeLists,
- Region->MemMapInfo.AllocatedUser / BlockSize);
- DCHECK_GE(Region->FreeListInfo.PoppedBlocks,
- Region->FreeListInfo.PushedBlocks);
- const uptr BlocksInUse =
- Region->FreeListInfo.PoppedBlocks - Region->FreeListInfo.PushedBlocks;
- DCHECK_EQ(BlocksInUse, BatchClassUsedInFreeLists);
+ DCHECK_EQ(TotalBlocks + BatchClassUsedInFreeLists,
+ RegionInfoIter->MemMapInfo.AllocatedUser / BlockSize);
+ DCHECK_GE(RegionInfoIter->FreeListInfo.PoppedBlocks,
+ RegionInfoIter->FreeListInfo.PushedBlocks);
+ const uptr BlocksInUse = RegionInfoIter->FreeListInfo.PoppedBlocks -
+ RegionInfoIter->FreeListInfo.PushedBlocks;
+ DCHECK_EQ(BlocksInUse, BatchClassUsedInFreeLists);
+ ++RegionInfoIter;
+ } while (!RegionInfoIter.end());
+
+ RegionInfoAllocator.verifyTheNumberOfAllocatedRegionInfo(NumRegionInfo);
}
u16 popBlocks(CacheT *C, uptr ClassId, CompactPtrT *ToArray,
const u16 MaxBlockCount) {
DCHECK_LT(ClassId, NumClasses);
- RegionInfo *Region = getRegionInfo(ClassId);
+ auto RegionInfoIter = RegionInfoManager.getRegionInfoIter(ClassId);
u16 PopCount = 0;
- {
- ScopedLock L(Region->FLLock);
- PopCount = popBlocksImpl(C, ClassId, Region, ToArray, MaxBlockCount);
- if (PopCount != 0U)
- return PopCount;
- }
+ do {
+ {
+ ScopedLock FL(RegionInfoIter->FLLock);
+ PopCount = popBlocksImpl(C, ClassId, RegionInfoIter.get(), ToArray,
+ MaxBlockCount);
+ if (PopCount != 0U)
+ return PopCount;
+ }
+
+ ++RegionInfoIter;
+ } while (!RegionInfoIter.end());
bool ReportRegionExhausted = false;
- if (conditionVariableEnabled()) {
+ RegionInfo *Region = RegionInfoManager.getCurRegionInfo(ClassId);
+
+ // TODO(chiahungduan): Support multiple-regions with condition variable.
----------------
cferris1000 wrote:
Similar question, can we add DCHECK that will fail if condition is enabled but isn't supported.
Better if it could be a static_assert to cause a compilation failure.
https://github.com/llvm/llvm-project/pull/98076
More information about the llvm-commits
mailing list