From d2ab19b331e2dc802705d59383c6ed7553438384 Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Sat, 31 Aug 2019 18:47:49 -0400 Subject: [PATCH] ramfs: Drop now-unused Block* classes. --- src/add-ons/kernel/file_systems/ramfs/Block.h | 319 ---------- .../file_systems/ramfs/BlockAllocator.cpp | 429 ------------- .../file_systems/ramfs/BlockAllocator.h | 72 --- .../file_systems/ramfs/BlockAllocatorArea.cpp | 599 ------------------ .../file_systems/ramfs/BlockAllocatorArea.h | 179 ------ .../ramfs/BlockAllocatorAreaBucket.cpp | 53 -- .../ramfs/BlockAllocatorAreaBucket.h | 101 --- .../file_systems/ramfs/BlockAllocatorMisc.h | 38 -- .../ramfs/BlockReferenceManager.cpp | 133 ---- .../ramfs/BlockReferenceManager.h | 52 -- 10 files changed, 1975 deletions(-) delete mode 100644 src/add-ons/kernel/file_systems/ramfs/Block.h delete mode 100644 src/add-ons/kernel/file_systems/ramfs/BlockAllocator.cpp delete mode 100644 src/add-ons/kernel/file_systems/ramfs/BlockAllocator.h delete mode 100644 src/add-ons/kernel/file_systems/ramfs/BlockAllocatorArea.cpp delete mode 100644 src/add-ons/kernel/file_systems/ramfs/BlockAllocatorArea.h delete mode 100644 src/add-ons/kernel/file_systems/ramfs/BlockAllocatorAreaBucket.cpp delete mode 100644 src/add-ons/kernel/file_systems/ramfs/BlockAllocatorAreaBucket.h delete mode 100644 src/add-ons/kernel/file_systems/ramfs/BlockAllocatorMisc.h delete mode 100644 src/add-ons/kernel/file_systems/ramfs/BlockReferenceManager.cpp delete mode 100644 src/add-ons/kernel/file_systems/ramfs/BlockReferenceManager.h diff --git a/src/add-ons/kernel/file_systems/ramfs/Block.h b/src/add-ons/kernel/file_systems/ramfs/Block.h deleted file mode 100644 index 1a5bc7f404..0000000000 --- a/src/add-ons/kernel/file_systems/ramfs/Block.h +++ /dev/null @@ -1,319 +0,0 @@ -/* - * Copyright 2007, Ingo Weinhold, ingo_weinhold@gmx.de. - * All rights reserved. Distributed under the terms of the MIT license. - */ -#ifndef BLOCK_H -#define BLOCK_H - -class Block; -class BlockHeader; -class BlockReference; -class TFreeBlock; - -#include - -// debugging -//#define inline -#define BA_DEFINE_INLINES 1 - -// BlockHeader -class BlockHeader { -public: - inline Block *ToBlock() { return (Block*)this; } - inline TFreeBlock *ToFreeBlock() { return (TFreeBlock*)this; } - - inline void SetPreviousBlock(Block *block); - inline Block *GetPreviousBlock(); - - inline void SetNextBlock(Block *block); - inline Block *GetNextBlock(); - inline bool HasNextBlock() { return (fSize & HAS_NEXT_FLAG); } - - inline void SetSize(size_t size, bool hasNext = false); - inline size_t GetSize() const; - static inline size_t GetUsableSizeFor(size_t size); - inline size_t GetUsableSize() const; - - inline void *GetData(); - - inline void SetFree(bool flag); - inline bool IsFree() const; - - inline void SetReference(BlockReference *ref); - inline BlockReference *GetReference() const { return fReference; } - inline void FixReference(); - - inline void SetTo(Block *previous, size_t size, bool isFree, bool hasNext, - BlockReference *reference = NULL); - -private: - enum { - FREE_FLAG = 0x80000000, - BACK_SKIP_MASK = 0x7fffffff, - }; - - enum { - HAS_NEXT_FLAG = 0x80000000, - SIZE_MASK = 0x7fffffff, - }; - -protected: - BlockHeader(); - ~BlockHeader(); - -protected: - size_t fBackSkip; - size_t fSize; - BlockReference *fReference; -}; - -// Block -class Block : public BlockHeader { -public: - static inline Block *MakeBlock(void *address, ssize_t offset, - Block *previous, size_t size, bool isFree, - bool hasNext, - BlockReference *reference = NULL); - -protected: - Block(); - ~Block(); -}; - -// TFreeBlock -class TFreeBlock : public Block { -public: - - inline void SetPreviousFreeBlock(TFreeBlock *block) { fPrevious = block; } - inline void SetNextFreeBlock(TFreeBlock *block) { fNext = block; } - inline TFreeBlock *GetPreviousFreeBlock() { return fPrevious; } - inline TFreeBlock *GetNextFreeBlock() { return fNext; } - - inline void SetTo(Block *previous, size_t size, bool hasNext, - TFreeBlock *previousFree, TFreeBlock *nextFree); - -// static inline TFreeBlock *MakeFreeBlock(void *address, ssize_t offset, -// Block *previous, size_t size, bool hasNext, TFreeBlock *previousFree, -// TFreeBlock *nextFree); - -protected: - TFreeBlock(); - ~TFreeBlock(); - -private: - TFreeBlock *fPrevious; - TFreeBlock *fNext; -}; - -// BlockReference -class BlockReference { -public: - inline BlockReference() : fBlock(NULL) {} - inline BlockReference(Block *block) : fBlock(block) {} - - inline void SetBlock(Block *block) { fBlock = block; } - inline Block *GetBlock() const { return fBlock; } - - inline void *GetData() const { return fBlock->GetData(); } - inline void *GetDataAt(ssize_t offset) const; - -private: - Block *fBlock; -}; - - -// --------------------------------------------------------------------------- -// inline methods - -// debugging -#if BA_DEFINE_INLINES - -// BlockHeader - -// SetPreviousBlock -inline -void -BlockHeader::SetPreviousBlock(Block *block) -{ - size_t offset = (block ? (char*)this - (char*)block : 0); - fBackSkip = (fBackSkip & FREE_FLAG) | offset; -} - -// GetPreviousBlock -inline -Block * -BlockHeader::GetPreviousBlock() -{ - if (fBackSkip & BACK_SKIP_MASK) - return (Block*)((char*)this - (fBackSkip & BACK_SKIP_MASK)); - return NULL; -} - -// SetNextBlock -inline -void -BlockHeader::SetNextBlock(Block *block) -{ - if (block) - fSize = ((char*)block - (char*)this) | HAS_NEXT_FLAG; - else - fSize &= SIZE_MASK; -} - -// GetNextBlock -inline -Block * -BlockHeader::GetNextBlock() -{ - if (fSize & HAS_NEXT_FLAG) - return (Block*)((char*)this + (SIZE_MASK & fSize)); - return NULL; -} - -// SetSize -inline -void -BlockHeader::SetSize(size_t size, bool hasNext) -{ - fSize = size; - if (hasNext) - fSize |= HAS_NEXT_FLAG; -} - -// GetSize -inline -size_t -BlockHeader::GetSize() const -{ - return (fSize & SIZE_MASK); -} - -// GetUsableSizeFor -inline -size_t -BlockHeader::GetUsableSizeFor(size_t size) -{ - return (size - sizeof(BlockHeader)); -} - -// GetUsableSize -inline -size_t -BlockHeader::GetUsableSize() const -{ - return GetUsableSizeFor(GetSize()); -} - -// GetData -inline -void * -BlockHeader::GetData() -{ - return (char*)this + sizeof(BlockHeader); -} - -// SetFree -inline -void -BlockHeader::SetFree(bool flag) -{ - if (flag) - fBackSkip |= FREE_FLAG; - else - fBackSkip &= ~FREE_FLAG; -} - -// IsFree -inline -bool -BlockHeader::IsFree() const -{ - return (fBackSkip & FREE_FLAG); -} - -// SetTo -inline -void -BlockHeader::SetTo(Block *previous, size_t size, bool isFree, bool hasNext, - BlockReference *reference) -{ - SetPreviousBlock(previous); - SetSize(size, hasNext); - SetFree(isFree); - SetReference(reference); -} - -// SetReference -inline -void -BlockHeader::SetReference(BlockReference *ref) -{ - fReference = ref; - FixReference(); -} - -// FixReference -inline -void -BlockHeader::FixReference() -{ - if (fReference) - fReference->SetBlock(ToBlock()); -} - - -// Block - -// MakeBlock -/*inline -Block * -Block::MakeBlock(void *address, ssize_t offset, Block *previous, size_t size, - bool isFree, bool hasNext, BlockReference *reference) -{ - Block *block = (Block*)((char*)address + offset); - block->SetTo(previous, size, isFree, hasNext, reference); - return block; -}*/ - - -// TFreeBlock - -// SetTo -inline -void -TFreeBlock::SetTo(Block *previous, size_t size, bool hasNext, - TFreeBlock *previousFree, TFreeBlock *nextFree) -{ - Block::SetTo(previous, size, true, hasNext, NULL); - SetPreviousFreeBlock(previousFree); - SetNextFreeBlock(nextFree); -} - -// MakeFreeBlock -/*inline -TFreeBlock * -TFreeBlock::MakeFreeBlock(void *address, ssize_t offset, Block *previous, - size_t size, bool hasNext, TFreeBlock *previousFree, - TFreeBlock *nextFree) -{ - TFreeBlock *block = (TFreeBlock*)((char*)address + offset); - block->SetTo(previous, size, hasNext, previousFree, nextFree); - if (hasNext) - block->GetNextBlock()->SetPreviousBlock(block); - return block; -}*/ - - -// BlockReference - -// GetDataAt -inline -void * -BlockReference::GetDataAt(ssize_t offset) const -{ - return (char*)fBlock->GetData() + offset; -} - -#endif // BA_DEFINE_INLINES - -#endif // BLOCK_H diff --git a/src/add-ons/kernel/file_systems/ramfs/BlockAllocator.cpp b/src/add-ons/kernel/file_systems/ramfs/BlockAllocator.cpp deleted file mode 100644 index 6e4c001b89..0000000000 --- a/src/add-ons/kernel/file_systems/ramfs/BlockAllocator.cpp +++ /dev/null @@ -1,429 +0,0 @@ -/* - * Copyright 2007, Ingo Weinhold, ingo_weinhold@gmx.de. - * All rights reserved. Distributed under the terms of the MIT license. - */ - -// debugging -#define BA_DEFINE_INLINES 1 - -#include "AllocationInfo.h" -#include "BlockAllocator.h" -#include "BlockAllocatorArea.h" -#include "BlockAllocatorAreaBucket.h" -#include "DebugSupport.h" - - -// BlockAllocator - -// constructor -BlockAllocator::BlockAllocator(size_t areaSize) - : fReferenceManager(), - fBuckets(NULL), - fBucketCount(0), - fAreaSize(areaSize), - fAreaCount(0), - fFreeBytes(0) -{ - // create and init buckets - fBucketCount = bucket_containing_size(areaSize) + 1; - fBuckets = new(nothrow) AreaBucket[fBucketCount]; - size_t minSize = 0; - for (int32 i = 0; i < fBucketCount; i++) { - size_t maxSize = (1 << i) * kMinNetBlockSize; - fBuckets[i].SetIndex(i); - fBuckets[i].SetSizeLimits(minSize, maxSize); - minSize = maxSize; - } -} - -// destructor -BlockAllocator::~BlockAllocator() -{ - if (fBuckets) - delete[] fBuckets; -} - -// InitCheck -status_t -BlockAllocator::InitCheck() const -{ - RETURN_ERROR(fBuckets ? B_OK : B_NO_MEMORY); -} - -// AllocateBlock -BlockReference * -BlockAllocator::AllocateBlock(size_t usableSize) -{ -#if ENABLE_BA_PANIC -if (fPanic) - return NULL; -#endif -//PRINT(("BlockAllocator::AllocateBlock(%lu)\n", usableSize)); - Block *block = NULL; - if (usableSize > 0 && usableSize <= Area::GetMaxFreeBytesFor(fAreaSize)) { - // get a block reference - BlockReference *reference = fReferenceManager.AllocateReference(); - if (reference) { - block = _AllocateBlock(usableSize); - // set reference / cleanup on failure - if (block) - block->SetReference(reference); - else - fReferenceManager.FreeReference(reference); - } - D(SanityCheck(false)); - } -//PRINT(("BlockAllocator::AllocateBlock() done: %p\n", block)); - return (block ? block->GetReference() : NULL); -} - -// FreeBlock -void -BlockAllocator::FreeBlock(BlockReference *blockReference) -{ -#if ENABLE_BA_PANIC -if (fPanic) - return; -#endif -D(if (!CheckBlock(blockReference)) return;); - Block *block = (blockReference ? blockReference->GetBlock() : NULL); -//PRINT(("BlockAllocator::FreeBlock(%p)\n", block)); - Area *area = NULL; - if (block && !block->IsFree() && (area = _AreaForBlock(block)) != NULL) { - _FreeBlock(area, block, true); - D(SanityCheck(false)); - if (_DefragmentingRecommended()) - _Defragment(); - } -//PRINT(("BlockAllocator::FreeBlock() done\n")); -} - -// ResizeBlock -BlockReference * -BlockAllocator::ResizeBlock(BlockReference *blockReference, size_t usableSize) -{ -#if ENABLE_BA_PANIC -if (fPanic) - return NULL; -#endif -D(if (!CheckBlock(blockReference)) return NULL;); -//PRINT(("BlockAllocator::ResizeBlock(%p, %lu)\n", blockReference, usableSize)); - Block *block = (blockReference ? blockReference->GetBlock() : NULL); - Block *resultBlock = NULL; - Area *area = NULL; - if (block && !block->IsFree() && (area = _AreaForBlock(block)) != NULL) { -//PRINT(("BlockAllocator::ResizeBlock(%p, %lu)\n", block, usableSize)); - if (usableSize) { - // try to let the area resize the block - size_t blockSize = block->GetSize(); - size_t areaFreeBytes = area->GetFreeBytes(); - bool needsDefragmenting = area->NeedsDefragmenting(); -//PRINT((" block reference: %p / %p\n", blockReference, block->GetReference())); - resultBlock = area->ResizeBlock(block, usableSize); - block = blockReference->GetBlock(); - if (resultBlock) { -//PRINT((" area succeeded in resizing the block\n")); -//PRINT((" block reference now: %p\n", resultBlock->GetReference())); - // the area was able to resize the block - _RethinkAreaBucket(area, area->GetBucket(), - needsDefragmenting); - fFreeBytes = fFreeBytes + area->GetFreeBytes() - areaFreeBytes; - // Defragment only, if the area was able to resize the block, - // the new block is smaller than the old one and defragmenting - // is recommended. - if (blockSize > resultBlock->GetSize() - && _DefragmentingRecommended()) { - _Defragment(); - } - } else { -//PRINT((" area failed to resize the block\n")); - // the area failed: allocate a new block, copy the data, and - // free the old one - resultBlock = _AllocateBlock(usableSize); - block = blockReference->GetBlock(); - if (resultBlock) { - memcpy(resultBlock->GetData(), block->GetData(), - block->GetUsableSize()); - resultBlock->SetReference(block->GetReference()); - _FreeBlock(area, block, false); - } - } - } else - FreeBlock(blockReference); - D(SanityCheck(false)); -//PRINT(("BlockAllocator::ResizeBlock() done: %p\n", resultBlock)); - } - return (resultBlock ? resultBlock->GetReference() : NULL); -} - -// SanityCheck -bool -BlockAllocator::SanityCheck(bool deep) const -{ - // iterate through all areas of all buckets - int32 areaCount = 0; - size_t freeBytes = 0; - for (int32 i = 0; i < fBucketCount; i++) { - AreaBucket *bucket = fBuckets + i; - if (deep) { - if (!bucket->SanityCheck(deep)) - return false; - } - for (Area *area = bucket->GetFirstArea(); - area; - area = bucket->GetNextArea(area)) { - areaCount++; - freeBytes += area->GetFreeBytes(); - } - } - // area count - if (areaCount != fAreaCount) { - FATAL("fAreaCount is %" B_PRId32 ", but should be %" B_PRId32 "\n", fAreaCount, - areaCount); - BA_PANIC("BlockAllocator: Bad free bytes."); - return false; - } - // free bytes - if (fFreeBytes != freeBytes) { - FATAL("fFreeBytes is %lu, but should be %lu\n", fFreeBytes, - freeBytes); - BA_PANIC("BlockAllocator: Bad free bytes."); - return false; - } - return true; -} - -// CheckArea -bool -BlockAllocator::CheckArea(Area *checkArea) -{ - for (int32 i = 0; i < fBucketCount; i++) { - AreaBucket *bucket = fBuckets + i; - for (Area *area = bucket->GetFirstArea(); - area; - area = bucket->GetNextArea(area)) { - if (area == checkArea) - return true; - } - } - FATAL("Area %p is not a valid Area!\n", checkArea); - BA_PANIC("Invalid Area."); - return false; -} - -// CheckBlock -bool -BlockAllocator::CheckBlock(Block *block, size_t minSize) -{ - Area *area = _AreaForBlock(block); - return (area/* && CheckArea(area)*/ && area->CheckBlock(block, minSize)); -} - -// CheckBlock -bool -BlockAllocator::CheckBlock(BlockReference *reference, size_t minSize) -{ - return (fReferenceManager.CheckReference(reference) - && CheckBlock(reference->GetBlock(), minSize)); -} - -// GetAllocationInfo -void -BlockAllocator::GetAllocationInfo(AllocationInfo &info) -{ - fReferenceManager.GetAllocationInfo(info); - info.AddOtherAllocation(sizeof(AreaBucket), fBucketCount); - info.AddAreaAllocation(fAreaSize, fAreaCount); -} - -// _AreaForBlock -inline -BlockAllocator::Area * -BlockAllocator::_AreaForBlock(Block *block) -{ - Area *area = NULL; - area_id id = area_for(block); - area_info info; - if (id >= 0 && get_area_info(id, &info) == B_OK) - area = (Area*)info.address; -D(if (!CheckArea(area)) return NULL;); - return area; -} - -// _AllocateBlock -Block * -BlockAllocator::_AllocateBlock(size_t usableSize, bool dontCreateArea) -{ - Block *block = NULL; - // Get the last area (the one with the most free space) and try - // to let it allocate a block. If that fails, allocate a new area. - // find a bucket for the allocation -// TODO: optimize - AreaBucket *bucket = NULL; - int32 index = bucket_containing_min_size(usableSize); - for (; index < fBucketCount; index++) { - if (!fBuckets[index].IsEmpty()) { - bucket = fBuckets + index; - break; - } - } - // get an area: if we have one, from the bucket, else create a new - // area - Area *area = NULL; - if (bucket) - area = bucket->GetFirstArea(); - else if (!dontCreateArea) { - area = Area::Create(fAreaSize); - if (area) { - fAreaCount++; - fFreeBytes += area->GetFreeBytes(); - bucket = fBuckets + area->GetBucketIndex(); - bucket->AddArea(area); -PRINT("New area allocated. area count now: %" B_PRId32 ", free bytes: %lu\n", -fAreaCount, fFreeBytes); - } - } - // allocate a block - if (area) { - size_t areaFreeBytes = area->GetFreeBytes(); - bool needsDefragmenting = area->NeedsDefragmenting(); - block = area->AllocateBlock(usableSize); - // move the area into another bucket, if necessary - if (block) { - _RethinkAreaBucket(area, bucket, needsDefragmenting); - fFreeBytes = fFreeBytes + area->GetFreeBytes() - areaFreeBytes; - } -#if ENABLE_BA_PANIC -else if (!fPanic) { -FATAL("Block allocation failed unexpectedly.\n"); -PRINT(" usableSize: %lu, areaFreeBytes: %lu\n", usableSize, areaFreeBytes); -BA_PANIC("Block allocation failed unexpectedly."); -//block = area->AllocateBlock(usableSize); -} -#endif - } - return block; -} - -// _FreeBlock -void -BlockAllocator::_FreeBlock(Area *area, Block *block, bool freeReference) -{ - size_t areaFreeBytes = area->GetFreeBytes(); - AreaBucket *bucket = area->GetBucket(); - bool needsDefragmenting = area->NeedsDefragmenting(); - // free the block and the block reference - BlockReference *reference = block->GetReference(); - area->FreeBlock(block); - if (reference && freeReference) - fReferenceManager.FreeReference(reference); - // move the area into another bucket, if necessary - _RethinkAreaBucket(area, bucket, needsDefragmenting); - fFreeBytes = fFreeBytes + area->GetFreeBytes() - areaFreeBytes; -} - -// _RethinkAreaBucket -inline -void -BlockAllocator::_RethinkAreaBucket(Area *area, AreaBucket *bucket, - bool needsDefragmenting) -{ - AreaBucket *newBucket = fBuckets + area->GetBucketIndex(); - if (newBucket != bucket - || needsDefragmenting != area->NeedsDefragmenting()) { - bucket->RemoveArea(area); - newBucket->AddArea(area); - } -} - -// _DefragmentingRecommended -inline -bool -BlockAllocator::_DefragmentingRecommended() -{ - // Don't know, whether this makes much sense: We don't try to defragment, - // when not at least a complete area could be deleted, and some tolerance - // being left (a fixed value plus 1/32 of the used bytes). - size_t usedBytes = fAreaCount * Area::GetMaxFreeBytesFor(fAreaSize) - - fFreeBytes; - return (fFreeBytes > fAreaSize + kDefragmentingTolerance + usedBytes / 32); -} - -// _Defragment -bool -BlockAllocator::_Defragment() -{ - bool success = false; - // We try to empty the least populated area by moving its blocks to other - // areas. - if (fFreeBytes > fAreaSize) { - // find the least populated area - // find the bucket with the least populated areas - AreaBucket *bucket = NULL; - for (int32 i = fBucketCount - 1; i >= 0; i--) { - if (!fBuckets[i].IsEmpty()) { - bucket = fBuckets + i; - break; - } - } - // find the area in the bucket - Area *area = NULL; - if (bucket) { - area = bucket->GetFirstArea(); - Area *bucketArea = area; - while ((bucketArea = bucket->GetNextArea(bucketArea)) != NULL) { - if (bucketArea->GetFreeBytes() > area->GetFreeBytes()) - area = bucketArea; - } - } - if (area) { - // remove the area from the bucket - bucket->RemoveArea(area); - fFreeBytes -= area->GetFreeBytes(); - // iterate through the blocks in the area and try to find a new - // home for them - success = true; - while (Block *block = area->GetFirstUsedBlock()) { - Block *newBlock = _AllocateBlock(block->GetUsableSize(), true); - if (newBlock) { - // got a new block: copy the data to it and free the old - // one - memcpy(newBlock->GetData(), block->GetData(), - block->GetUsableSize()); - newBlock->SetReference(block->GetReference()); - block->SetReference(NULL); - area->FreeBlock(block, true); -#if ENABLE_BA_PANIC - if (fPanic) { - PRINT("Panicked while trying to free block %p\n", - block); - success = false; - break; - } -#endif - } else { - success = false; - break; - } - } - // delete the area - if (success && area->IsEmpty()) { - area->Delete(); - fAreaCount--; -PRINT("defragmenting: area deleted\n"); - } else { -PRINT("defragmenting: failed to empty area\n"); - // failed: re-add the area - fFreeBytes += area->GetFreeBytes(); - AreaBucket *newBucket = fBuckets + area->GetBucketIndex(); - newBucket->AddArea(area); - } - } - D(SanityCheck(false)); - } - return success; -} - -#if ENABLE_BA_PANIC -bool BlockAllocator::fPanic = false; -#endif diff --git a/src/add-ons/kernel/file_systems/ramfs/BlockAllocator.h b/src/add-ons/kernel/file_systems/ramfs/BlockAllocator.h deleted file mode 100644 index 87254f0f98..0000000000 --- a/src/add-ons/kernel/file_systems/ramfs/BlockAllocator.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2007, Ingo Weinhold, ingo_weinhold@gmx.de. - * All rights reserved. Distributed under the terms of the MIT license. - */ -#ifndef BLOCK_ALLOCATOR_H -#define BLOCK_ALLOCATOR_H - -#include - -#include "Block.h" -#include "BlockReferenceManager.h" -#include "DebugSupport.h" -#include "List.h" - -#define ENABLE_BA_PANIC 1 -#if ENABLE_BA_PANIC -#define BA_PANIC(x) { PANIC(x); BlockAllocator::fPanic = true; } -#endif - -class AllocationInfo; - -// BlockAllocator -class BlockAllocator { -public: - BlockAllocator(size_t areaSize); - ~BlockAllocator(); - - status_t InitCheck() const; - - BlockReference *AllocateBlock(size_t usableSize); - void FreeBlock(BlockReference *block); - BlockReference *ResizeBlock(BlockReference *block, size_t usableSize); - - size_t GetAvailableBytes() const { return fAreaCount * fAreaSize; } - size_t GetFreeBytes() const { return fFreeBytes; } - size_t GetUsedBytes() const { return fAreaCount * fAreaSize - - fFreeBytes; } - -public: - class Area; - class AreaBucket; - - // debugging only - bool SanityCheck(bool deep = false) const; - bool CheckArea(Area *area); - bool CheckBlock(Block *block, size_t minSize = 0); - bool CheckBlock(BlockReference *reference, size_t minSize = 0); - void GetAllocationInfo(AllocationInfo &info); - -private: - inline Area *_AreaForBlock(Block *block); - Block *_AllocateBlock(size_t usableSize, bool dontCreateArea = false); - void _FreeBlock(Area *area, Block *block, bool freeReference); - inline void _RethinkAreaBucket(Area *area, AreaBucket *bucket, - bool needsDefragmenting); - inline bool _DefragmentingRecommended(); - bool _Defragment(); - -private: - BlockReferenceManager fReferenceManager; - AreaBucket *fBuckets; - int32 fBucketCount; - size_t fAreaSize; - int32 fAreaCount; - size_t fFreeBytes; -#if ENABLE_BA_PANIC -public: - static bool fPanic; -#endif -}; - -#endif // BLOCK_ALLOCATOR_H diff --git a/src/add-ons/kernel/file_systems/ramfs/BlockAllocatorArea.cpp b/src/add-ons/kernel/file_systems/ramfs/BlockAllocatorArea.cpp deleted file mode 100644 index 7382998e0a..0000000000 --- a/src/add-ons/kernel/file_systems/ramfs/BlockAllocatorArea.cpp +++ /dev/null @@ -1,599 +0,0 @@ -/* - * Copyright 2007, Ingo Weinhold, ingo_weinhold@gmx.de. - * All rights reserved. Distributed under the terms of the MIT license. - */ - -#include "BlockAllocatorArea.h" -#include "DebugSupport.h" - -// constructor -BlockAllocator::Area::Area(area_id id, size_t size) - : fBucket(NULL), - fID(id), - fSize(size), - fFreeBytes(0), - fFreeBlockCount(1), - fUsedBlockCount(0), - fFirstBlock(NULL), - fLastBlock(NULL), - fFirstFree(NULL), - fLastFree(NULL) -{ - size_t headerSize = block_align_ceil(sizeof(Area)); - fFirstFree = (TFreeBlock*)((char*)this + headerSize); - fFirstFree->SetTo(NULL, block_align_floor(fSize - headerSize), false, NULL, - NULL); - fFirstBlock = fLastBlock = fLastFree = fFirstFree; - fFreeBytes = fFirstFree->GetUsableSize(); -} - -// Create -BlockAllocator::Area * -BlockAllocator::Area::Create(size_t size) -{ - Area *area = NULL; - void *base = NULL; -#if USER - area_id id = create_area("block alloc", &base, B_ANY_ADDRESS, - size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); -#else - area_id id = create_area("block alloc", &base, B_ANY_KERNEL_ADDRESS, - size, B_FULL_LOCK, B_READ_AREA | B_WRITE_AREA); -#endif - if (id >= 0) { - area = new(base) Area(id, size); - } else { - ERROR("BlockAllocator::Area::Create(%lu): Failed to create area: %s\n", - size, strerror(id)); - } - return area; -} - -// Delete -void -BlockAllocator::Area::Delete() -{ - delete_area(fID); -} - -// AllocateBlock -Block * -BlockAllocator::Area::AllocateBlock(size_t usableSize, bool dontDefragment) -{ -if (kMinBlockSize != block_align_ceil(sizeof(TFreeBlock))) { -FATAL("kMinBlockSize is not correctly initialized! Is %lu, but should be: " -"%lu\n", kMinBlockSize, block_align_ceil(sizeof(TFreeBlock))); -BA_PANIC("kMinBlockSize not correctly initialized."); -return NULL; -} - if (usableSize == 0) - return NULL; - Block *newBlock = NULL; - size_t size = max(usableSize + sizeof(BlockHeader), kMinBlockSize); - size = block_align_ceil(size); - if (size <= _GetBlockFreeBytes()) { - // find first fit - TFreeBlock *block = _FindFreeBlock(size); - if (!block && !dontDefragment) { - // defragmenting is necessary - _Defragment(); - block = _FindFreeBlock(size); - if (!block) { - // no free block - // Our data structures seem to be corrupted, since - // _GetBlockFreeBytes() promised that we would have enough - // free space. - FATAL("Couldn't find free block of min size %lu after " - "defragmenting, although we should have %lu usable free " - "bytes!\n", size, _GetBlockFreeBytes()); - BA_PANIC("Bad area free bytes."); - } - } - if (block) { - // found a free block - size_t remainder = block->GetSize() - size; - if (remainder >= kMinBlockSize) { - // enough space left for a free block - Block *freePrev = block->GetPreviousBlock(); -// TFreeBlock *prevFree = block->GetPreviousFreeBlock(); -// TFreeBlock *nextFree = block->GetNextFreeBlock(); -// newBlock = block; - _MoveResizeFreeBlock(block, size, remainder); - // setup the new block -// newBlock->SetSize(size, true); -// newBlock->SetFree(false); - newBlock = _MakeUsedBlock(block, 0, freePrev, size, true); - } else { - // not enough space left: take the free block over completely - // remove the block from the free list - _RemoveFreeBlock(block); - newBlock = block; - newBlock->SetFree(false); - } - if (fFreeBlockCount) - fFreeBytes -= newBlock->GetSize(); - else - fFreeBytes = 0; - fUsedBlockCount++; - } - } - D(SanityCheck()); - return newBlock; -} - -// FreeBlock -void -BlockAllocator::Area::FreeBlock(Block *block, bool dontDefragment) -{ - if (block) { - // mark the block free and insert it into the free list - block->SetFree(true); - TFreeBlock *freeBlock = (TFreeBlock*)block; - _InsertFreeBlock(freeBlock); - fUsedBlockCount--; - if (fFreeBlockCount == 1) - fFreeBytes += freeBlock->GetUsableSize(); - else - fFreeBytes += freeBlock->GetSize(); - // try coalescing with the next and the previous free block -D(SanityCheck()); - _CoalesceWithNext(freeBlock); -D(SanityCheck()); - _CoalesceWithNext(freeBlock->GetPreviousFreeBlock()); - // defragment, if sensible - if (!dontDefragment && _DefragmentingRecommended()) - _Defragment(); - D(SanityCheck()); - } -} - -// ResizeBlock -Block * -BlockAllocator::Area::ResizeBlock(Block *block, size_t newUsableSize, - bool dontDefragment) -{ -//PRINT(("Area::ResizeBlock(%p, %lu)\n", block, newUsableSize)); -// newUsableSize must be >0 ! - if (newUsableSize == 0) - return NULL; - Block *resultBlock = NULL; - if (block) { - size_t size = block->GetSize(); - size_t newSize = max(newUsableSize + sizeof(BlockHeader), - kMinBlockSize); - newSize = block_align_ceil(newSize); - if (newSize == size) { - // size doesn't change: nothing to do - resultBlock = block; - } else if (newSize < size) { - // shrink the block - size_t sizeDiff = size - newSize; - Block *nextBlock = block->GetNextBlock(); - if (nextBlock && nextBlock->IsFree()) { - // join the space with the adjoining free block - TFreeBlock *freeBlock = nextBlock->ToFreeBlock(); - _MoveResizeFreeBlock(freeBlock, -sizeDiff, - freeBlock->GetSize() + sizeDiff); - // resize the block and we're done - block->SetSize(newSize, true); - fFreeBytes += sizeDiff; - } else if (sizeDiff >= sizeof(TFreeBlock)) { - // the freed space is large enough for a free block - TFreeBlock *newFree = _MakeFreeBlock(block, newSize, block, - sizeDiff, nextBlock, NULL, NULL); - _InsertFreeBlock(newFree); - block->SetSize(newSize, true); - if (fFreeBlockCount == 1) - fFreeBytes += newFree->GetUsableSize(); - else - fFreeBytes += newFree->GetSize(); - if (!dontDefragment && _DefragmentingRecommended()) - _Defragment(); - } // else: insufficient space for a free block: no changes - resultBlock = block; - } else { -//PRINT((" grow...\n")); - // grow the block - size_t sizeDiff = newSize - size; - Block *nextBlock = block->GetNextBlock(); - if (nextBlock && nextBlock->IsFree() - && nextBlock->GetSize() >= sizeDiff) { -//PRINT((" adjoining free block\n")); - // there is a adjoining free block and it is large enough - TFreeBlock *freeBlock = nextBlock->ToFreeBlock(); - size_t freeSize = freeBlock->GetSize(); - if (freeSize - sizeDiff >= sizeof(TFreeBlock)) { - // the remaining space is still large enough for a free - // block - _MoveResizeFreeBlock(freeBlock, sizeDiff, - freeSize - sizeDiff); - block->SetSize(newSize, true); - fFreeBytes -= sizeDiff; - } else { - // the remaining free space wouldn't be large enough for - // a free block: consume the free block completely - Block *freeNext = freeBlock->GetNextBlock(); - _RemoveFreeBlock(freeBlock); - block->SetSize(size + freeSize, freeNext); - _FixBlockList(block, block->GetPreviousBlock(), freeNext); - if (fFreeBlockCount == 0) - fFreeBytes = 0; - else - fFreeBytes -= freeSize; - } - resultBlock = block; - } else { -//PRINT((" no adjoining free block\n")); - // no (large enough) adjoining free block: allocate - // a new block and copy the data to it - BlockReference *reference = block->GetReference(); - resultBlock = AllocateBlock(newUsableSize, dontDefragment); - block = reference->GetBlock(); - if (resultBlock) { - resultBlock->SetReference(reference); - memcpy(resultBlock->GetData(), block->GetData(), - block->GetUsableSize()); - FreeBlock(block, dontDefragment); - resultBlock = reference->GetBlock(); - } - } - } - } - D(SanityCheck()); -//PRINT(("Area::ResizeBlock() done: %p\n", resultBlock)); - return resultBlock; -} - -// SanityCheck -bool -BlockAllocator::Area::SanityCheck() const -{ - // area ID - if (fID < 0) { - FATAL("Area ID < 0: %" B_PRIx32 "\n", fID); - BA_PANIC("Bad area ID."); - return false; - } - // size - size_t areaHeaderSize = block_align_ceil(sizeof(Area)); - if (fSize < areaHeaderSize + sizeof(TFreeBlock)) { - FATAL("Area too small to contain area header and at least one free " - "block: %lu bytes\n", fSize); - BA_PANIC("Bad area size."); - return false; - } - // free bytes - if (fFreeBytes > fSize) { - FATAL("Free size greater than area size: %lu vs %lu\n", fFreeBytes, - fSize); - BA_PANIC("Bad area free bytes."); - return false; - } - // block count - if (fFreeBlockCount + fUsedBlockCount == 0) { - FATAL("Area contains no blocks at all.\n"); - BA_PANIC("Bad area block count."); - return false; - } - // block list - uint32 usedBlockCount = 0; - uint32 freeBlockCount = 0; - size_t freeBytes = 0; - if (!fFirstBlock || !fLastBlock) { - FATAL("Invalid block list: first or last block NULL: first: %p, " - "last: %p\n", fFirstBlock, fLastBlock); - BA_PANIC("Bad area block list."); - return false; - } else { - // iterate through block list and also check free list - int32 blockCount = fFreeBlockCount + fUsedBlockCount; - Block *block = fFirstBlock; - Block *prevBlock = NULL; - Block *prevFree = NULL; - Block *nextFree = fFirstFree; - bool blockListOK = true; - for (int32 i = 0; i < blockCount; i++) { - blockListOK = false; - if (!block) { - FATAL("Encountered NULL in block list at index %" B_PRId32 ", although " - "list should have %" B_PRId32 " blocks\n", i, blockCount); - BA_PANIC("Bad area block list."); - return false; - } - uint64 address = (addr_t)block; - // block within area? - if (address < (addr_t)this + areaHeaderSize - || address + sizeof(TFreeBlock) > (addr_t)this + fSize) { - FATAL("Utterly mislocated block: %p, area: %p, " - "size: %lu\n", block, this, fSize); - BA_PANIC("Bad area block."); - return false; - } - // block too large for area? - size_t blockSize = block->GetSize(); - if (blockSize < sizeof(TFreeBlock) - || address + blockSize > (addr_t)this + fSize) { - FATAL("Mislocated block: %p, size: %lu, area: %p, " - "size: %lu\n", block, blockSize, this, fSize); - BA_PANIC("Bad area block."); - return false; - } - // alignment - if (block_align_floor(address) != address - || block_align_floor(blockSize) != blockSize) { - FATAL("Block %" B_PRId32 " not properly aligned: %p, size: %lu\n", - i, block, blockSize); - BA_PANIC("Bad area block."); - return false; - } - // previous block - if (block->GetPreviousBlock() != prevBlock) { - FATAL("Previous block of block %" B_PRId32 " was not the previous " - "block in list: %p vs %p\n", i, - block->GetPreviousBlock(), prevBlock); - BA_PANIC("Bad area block list."); - return false; - } - // additional checks for free block list - if (block->IsFree()) { - freeBlockCount++; - TFreeBlock *freeBlock = block->ToFreeBlock(); - if (prevFree) - freeBytes += freeBlock->GetSize(); - else - freeBytes += freeBlock->GetUsableSize(); - // block == next free block of previous free block - if (freeBlock != nextFree) { - FATAL("Free block %" B_PRId32 " is not the next block in free " - "list: %p vs %p\n", i, freeBlock, nextFree); - BA_PANIC("Bad area free list."); - return false; - } - // previous free block - if (freeBlock->GetPreviousFreeBlock() != prevFree) { - FATAL("Previous free block of block %" B_PRId32 " was not the " - " previous block in free list: %p vs %p\n", i, - freeBlock->GetPreviousFreeBlock(), prevFree); - BA_PANIC("Bad area free list."); - return false; - } - prevFree = freeBlock; - nextFree = freeBlock->GetNextFreeBlock(); - } else - usedBlockCount++; - prevBlock = block; - block = block->GetNextBlock(); - blockListOK = true; - } - // final checks on block list - if (blockListOK) { - if (block) { - FATAL("More blocks in block list than expected\n"); - BA_PANIC("Bad area block count."); - return false; - } else if (fLastBlock != prevBlock) { - FATAL("last block in block list was %p, but should be " - "%p\n", fLastBlock, prevBlock); - BA_PANIC("Bad area last block."); - return false; - } else if (prevFree != fLastFree) { - FATAL("last block in free list was %p, but should be %p\n", - fLastFree, prevFree); - BA_PANIC("Bad area last free block."); - return false; - } - // block counts (a bit reduntant) - if (freeBlockCount != fFreeBlockCount) { - FATAL("Free block count is %" B_PRIuSIZE ", but should be %" B_PRIu32 "\n", - fFreeBlockCount, freeBlockCount); - BA_PANIC("Bad area free block count."); - return false; - } - if (usedBlockCount != fUsedBlockCount) { - FATAL("Used block count is %" B_PRIuSIZE ", but should be %" B_PRIu32 "\n", - fUsedBlockCount, usedBlockCount); - BA_PANIC("Bad area used block count."); - return false; - } - // free bytes - if (fFreeBytes != freeBytes) { - FATAL("Free bytes is %lu, but should be %lu\n", - fFreeBytes, freeBytes); - BA_PANIC("Bad area free bytes."); - return false; - } - } - } - return true; -} - -// CheckBlock -bool -BlockAllocator::Area::CheckBlock(Block *checkBlock, size_t minSize) -{ - for (Block *block = fFirstBlock; block; block = block->GetNextBlock()) { - if (block == checkBlock) - return (block->GetUsableSize() >= minSize); - } - FATAL("Block %p is not in area %p!\n", checkBlock, this); - BA_PANIC("Invalid Block."); - return false; -} - -// _FindFreeBlock -TFreeBlock * -BlockAllocator::Area::_FindFreeBlock(size_t minSize) -{ - // first fit - for (TFreeBlock *block = GetFirstFreeBlock(); - block; - block = block->GetNextFreeBlock()) { - if (block->GetSize() >= minSize) - return block; - } - return NULL; -} - -// _InsertFreeBlock -void -BlockAllocator::Area::_InsertFreeBlock(TFreeBlock *block) -{ - if (block) { - // find the free block before which this one has to be inserted - TFreeBlock *nextFree = NULL; - for (nextFree = GetFirstFreeBlock(); - nextFree; - nextFree = nextFree->GetNextFreeBlock()) { - if ((addr_t)nextFree > (addr_t)block) - break; - } - // get the previous block and insert the block between the two - TFreeBlock *prevFree - = (nextFree ? nextFree->GetPreviousFreeBlock() : fLastFree); - _FixFreeList(block, prevFree, nextFree); - fFreeBlockCount++; - } -} - -// _RemoveFreeBlock -void -BlockAllocator::Area::_RemoveFreeBlock(TFreeBlock *block) -{ - if (block) { - TFreeBlock *prevFree = block->GetPreviousFreeBlock(); - TFreeBlock *nextFree = block->GetNextFreeBlock(); - if (prevFree) - prevFree->SetNextFreeBlock(nextFree); - else - fFirstFree = nextFree; - if (nextFree) - nextFree->SetPreviousFreeBlock(prevFree); - else - fLastFree = prevFree; - } - fFreeBlockCount--; -} - -// _MoveResizeFreeBlock -TFreeBlock * -BlockAllocator::Area::_MoveResizeFreeBlock(TFreeBlock *freeBlock, - ssize_t offset, size_t newSize) -{ - TFreeBlock *movedFree = NULL; - if (freeBlock && offset) { - // move the header of the free block - Block *freePrev = freeBlock->GetPreviousBlock(); - TFreeBlock *prevFree = freeBlock->GetPreviousFreeBlock(); - TFreeBlock *nextFree = freeBlock->GetNextFreeBlock(); - movedFree = _MakeFreeBlock(freeBlock, offset, freePrev, newSize, - freeBlock->HasNextBlock(), prevFree, nextFree); - // update the free list - _FixFreeList(movedFree, prevFree, nextFree); - } - return movedFree; -} - -// _MakeFreeBlock -inline -TFreeBlock * -BlockAllocator::Area::_MakeFreeBlock(void *address, ssize_t offset, - Block *previous, size_t size, - bool hasNext, TFreeBlock *previousFree, - TFreeBlock *nextFree) -{ - TFreeBlock *block = (TFreeBlock*)((char*)address + offset); - block->SetTo(previous, size, hasNext, previousFree, nextFree); - if (hasNext) - block->GetNextBlock()->SetPreviousBlock(block); - else - fLastBlock = block; - return block; -} - -// _CoalesceWithNext -bool -BlockAllocator::Area::_CoalesceWithNext(TFreeBlock *block) -{ - bool result = false; - TFreeBlock *nextFree = NULL; - if (block && (nextFree = block->GetNextFreeBlock()) != NULL - && block->GetNextBlock() == nextFree) { - _RemoveFreeBlock(nextFree); - Block *nextBlock = nextFree->GetNextBlock(); - block->SetSize(block->GetSize() + nextFree->GetSize(), nextBlock); - if (nextBlock) - nextBlock->SetPreviousBlock(block); - else - fLastBlock = block; - result = true; - } - return result; -} - -// _MakeUsedBlock -inline -Block * -BlockAllocator::Area::_MakeUsedBlock(void *address, ssize_t offset, - Block *previous, size_t size, - bool hasNext) -{ - Block *block = (Block*)((char*)address + offset); - block->SetTo(previous, size, false, hasNext, NULL); - if (hasNext) - block->GetNextBlock()->SetPreviousBlock(block); - else - fLastBlock = block; - return block; -} - -// _Defragment -void -BlockAllocator::Area::_Defragment() -{ -D(SanityCheck()); -//PRINT(("BlockAllocator::Area::_Defragment()\n")); - // A trivial strategy for now: Keep the last free block and move the - // others so that they can be joined with it. This is done iteratively - // by moving the first free block to adjoin to the second one and - // coalescing them. A free block is moved by moving the data blocks in - // between. - TFreeBlock *nextFree = NULL; - while (fFirstFree && (nextFree = fFirstFree->GetNextFreeBlock()) != NULL) { - Block *prevBlock = fFirstFree->GetPreviousBlock(); - Block *nextBlock = fFirstFree->GetNextBlock(); - size_t size = fFirstFree->GetSize(); - // Used blocks are relatively position independed. We can move them - // en bloc and only need to adjust the previous pointer of the first - // one. - if (!nextBlock->IsFree()) { - // move the used blocks - size_t chunkSize = (char*)nextFree - (char*)nextBlock; - Block *nextFreePrev = nextFree->GetPreviousBlock(); - Block *movedBlock = fFirstFree; - memmove(movedBlock, nextBlock, chunkSize); - movedBlock->SetPreviousBlock(prevBlock); - // init the first free block - Block *movedNextFreePrev = (Block*)((char*)nextFreePrev - size); - fFirstFree = _MakeFreeBlock(movedBlock, chunkSize, - movedNextFreePrev, size, true, NULL, nextFree); - nextFree->SetPreviousFreeBlock(fFirstFree); - // fix the references of the moved blocks - for (Block *block = movedBlock; - block != fFirstFree; - block = block->GetNextBlock()) { - block->FixReference(); - } - } else { - // uncoalesced adjoining free block: That should never happen, - // since we always coalesce as early as possible. - INFORM(("Warning: Found uncoalesced adjoining free blocks!\n")); - } - // coalesce the first two blocks -D(SanityCheck()); - _CoalesceWithNext(fFirstFree); -D(SanityCheck()); - } -//D(SanityCheck()); -//PRINT(("BlockAllocator::Area::_Defragment() done\n")); -} - diff --git a/src/add-ons/kernel/file_systems/ramfs/BlockAllocatorArea.h b/src/add-ons/kernel/file_systems/ramfs/BlockAllocatorArea.h deleted file mode 100644 index 8700bc8bd4..0000000000 --- a/src/add-ons/kernel/file_systems/ramfs/BlockAllocatorArea.h +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright 2007, Ingo Weinhold, ingo_weinhold@gmx.de. - * All rights reserved. Distributed under the terms of the MIT license. - */ -#ifndef BLOCK_ALLOCATOR_AREA_H -#define BLOCK_ALLOCATOR_AREA_H - -#include - -#include "BlockAllocator.h" -#include "BlockAllocatorMisc.h" - - -class BlockAllocator::Area : public DoublyLinkedListLinkImpl { -public: - static Area *Create(size_t size); - void Delete(); - - inline void SetBucket(AreaBucket *bucket) { fBucket = bucket; } - inline AreaBucket *GetBucket() const { return fBucket; } - - inline Block *GetFirstBlock() const { return fFirstBlock; } - inline Block *GetLastBlock() const { return fLastBlock; } - - inline TFreeBlock *GetFirstFreeBlock() const { return fFirstFree; } - inline TFreeBlock *GetLastFreeBlock() const { return fLastFree; } - - inline bool IsEmpty() const { return (fUsedBlockCount == 0); } - inline Block *GetFirstUsedBlock() const; - - static inline size_t GetMaxFreeBytesFor(size_t areaSize); - - inline size_t GetFreeBytes() const { return fFreeBytes; } - inline bool NeedsDefragmenting() const { return (fFreeBlockCount > 1); } - - inline int32 GetBucketIndex(); - - Block *AllocateBlock(size_t usableSize, bool dontDefragment = false); - void FreeBlock(Block *block, bool dontDefragment = false); - Block *ResizeBlock(Block *block, size_t newSize, - bool dontDefragment = false); - - // debugging only - bool SanityCheck() const; - bool CheckBlock(Block *block, size_t minSize = 0); - -private: - inline size_t _GetBlockFreeBytes() - { return fFreeBytes + sizeof(BlockHeader); } - - Area(area_id id, size_t size); - ~Area(); - - inline void _FixBlockList(Block *block, Block *prevBlock, - Block *nextBlock); - inline void _FixFreeList(TFreeBlock *block, TFreeBlock *prevFree, - TFreeBlock *nextFree); - - TFreeBlock *_FindFreeBlock(size_t minSize); - void _InsertFreeBlock(TFreeBlock *block); - void _RemoveFreeBlock(TFreeBlock *block); - TFreeBlock * _MoveResizeFreeBlock(TFreeBlock *freeBlock, ssize_t offset, - size_t newSize); - inline TFreeBlock *_MakeFreeBlock(void *address, ssize_t offset, - Block *previous, size_t size, bool hasNext, TFreeBlock *previousFree, - TFreeBlock *nextFree); - bool _CoalesceWithNext(TFreeBlock *block); - - inline Block *_MakeUsedBlock(void *address, ssize_t offset, - Block *previous, size_t size, bool hasNext); - - inline bool _DefragmentingRecommended(); - void _Defragment(); - -private: - AreaBucket *fBucket; - area_id fID; - size_t fSize; - size_t fFreeBytes; - size_t fFreeBlockCount; - size_t fUsedBlockCount; - Block *fFirstBlock; - Block *fLastBlock; - TFreeBlock *fFirstFree; - TFreeBlock *fLastFree; -}; - -typedef BlockAllocator::Area Area; - - -// inline methods - -// debugging -#if BA_DEFINE_INLINES - -// GetFirstUsedBlock -inline -Block * -BlockAllocator::Area::GetFirstUsedBlock() const -{ - // Two assumptions: - // 1) There is always a first block. If that isn't so, our structure are - // corrupt. - // 2) If the first block is free, the second (if any) is not. Otherwise - // there were adjoining free blocks, which our coalescing strategy - // prevents. - return (fFirstBlock->IsFree() ? fFirstBlock->GetNextBlock() : fFirstBlock); -} - -// GetMaxFreeBytesFor -inline -size_t -BlockAllocator::Area::GetMaxFreeBytesFor(size_t areaSize) -{ - size_t headerSize = block_align_ceil(sizeof(Area)); - return Block::GetUsableSizeFor(block_align_floor(areaSize - headerSize)); -} - -// GetBucketIndex -inline -int32 -BlockAllocator::Area::GetBucketIndex() -{ - return bucket_containing_size(GetFreeBytes()); -} - -// _FixBlockList -inline -void -BlockAllocator::Area::_FixBlockList(Block *block, Block *prevBlock, - Block *nextBlock) -{ - if (block) { - if (prevBlock) - prevBlock->SetNextBlock(block); - else - fFirstBlock = block; - if (nextBlock) - nextBlock->SetPreviousBlock(block); - else - fLastBlock = block; - } -} - -// _FixFreeList -inline -void -BlockAllocator::Area::_FixFreeList(TFreeBlock *block, TFreeBlock *prevFree, - TFreeBlock *nextFree) -{ - if (block) { - if (prevFree) - prevFree->SetNextFreeBlock(block); - else - fFirstFree = block; - if (nextFree) - nextFree->SetPreviousFreeBlock(block); - else - fLastFree = block; - block->SetPreviousFreeBlock(prevFree); - block->SetNextFreeBlock(nextFree); - } -} - -// _DefragmentingRecommended -inline -bool -BlockAllocator::Area::_DefragmentingRecommended() -{ - // Defragmenting Condition: At least more than 5 free blocks and - // free / block ratio greater 1 / 10. Don't know, if that makes any - // sense. ;-) - return (fFreeBlockCount > 5 && fUsedBlockCount / fFreeBlockCount < 10); -} - -#endif // BA_DEFINE_INLINES - - -#endif // BLOCK_ALLOCATOR_AREA_H diff --git a/src/add-ons/kernel/file_systems/ramfs/BlockAllocatorAreaBucket.cpp b/src/add-ons/kernel/file_systems/ramfs/BlockAllocatorAreaBucket.cpp deleted file mode 100644 index 200c8cded0..0000000000 --- a/src/add-ons/kernel/file_systems/ramfs/BlockAllocatorAreaBucket.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2007, Ingo Weinhold, ingo_weinhold@gmx.de. - * All rights reserved. Distributed under the terms of the MIT license. - */ -#include "BlockAllocatorAreaBucket.h" - -// constructor -BlockAllocator::AreaBucket::AreaBucket() - : fAreas(), - fIndex(-1), - fMinSize(0), - fMaxSize(0) -{ -} - -// destructor -BlockAllocator::AreaBucket::~AreaBucket() -{ - while (Area *area = fAreas.First()) { - RemoveArea(area); - area->Delete(); - } -} - -// SanityCheck -bool -BlockAllocator::AreaBucket::SanityCheck(bool deep) const -{ - // check area list - for (Area *area = GetFirstArea(); area; area = GetNextArea(area)) { - if (deep) { - if (!area->SanityCheck()) - return false; - } - // bucket - if (area->GetBucket() != this) { - FATAL("Area %p is in bucket %p, but thinks it is in bucket %p\n", - area, this, area->GetBucket()); - BA_PANIC("Wrong area bucket."); - return false; - } - // size - size_t areaSize = area->GetFreeBytes(); - if (areaSize < fMinSize || areaSize >= fMaxSize) { - FATAL("Area is in wrong bucket: free: %lu, min: %lu, max: %lu\n", - areaSize, fMinSize, fMaxSize); - BA_PANIC("Area in wrong bucket."); - return false; - } - } - return true; -} - diff --git a/src/add-ons/kernel/file_systems/ramfs/BlockAllocatorAreaBucket.h b/src/add-ons/kernel/file_systems/ramfs/BlockAllocatorAreaBucket.h deleted file mode 100644 index 5af666c06b..0000000000 --- a/src/add-ons/kernel/file_systems/ramfs/BlockAllocatorAreaBucket.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2007, Ingo Weinhold, ingo_weinhold@gmx.de. - * All rights reserved. Distributed under the terms of the MIT license. - */ -#ifndef BLOCK_ALLOCATOR_AREA_BUCKET_H -#define BLOCK_ALLOCATOR_AREA_BUCKET_H - -#include - -#include "BlockAllocator.h" -#include "BlockAllocatorArea.h" -#include "DebugSupport.h" - - -class BlockAllocator::AreaBucket { -public: - AreaBucket(); - ~AreaBucket(); - - inline void SetIndex(int32 index) { fIndex = index; } - inline int32 GetIndex() const { return fIndex; } - - inline void SetSizeLimits(size_t minSize, size_t maxSize); - inline size_t GetMinSize() const { return fMinSize; } // incl. - inline size_t GetMaxSize() const { return fMaxSize; } // excl. - - inline void AddArea(Area *area); - inline void RemoveArea(Area *area); - - inline Area *GetFirstArea() const { return fAreas.First(); } - inline Area *GetLastArea() const { return fAreas.Last(); } - inline Area *GetNextArea(Area* area) const; - - inline bool IsEmpty() const { return fAreas.IsEmpty(); } - - // debugging only - bool SanityCheck(bool deep = false) const; - -private: - DoublyLinkedList fAreas; - int32 fIndex; - size_t fMinSize; - size_t fMaxSize; -}; - -typedef BlockAllocator::AreaBucket AreaBucket; - - -// inline methods - -// debugging -#if BA_DEFINE_INLINES - -// SetSizeLimits -/*! \brief Sets the size limits for areas this bucket may contain. - \param minSize Minimal area size. Inclusively. - \param maxSize Maximal area size. Exlusively. -*/ -inline -void -BlockAllocator::AreaBucket::SetSizeLimits(size_t minSize, size_t maxSize) -{ - fMinSize = minSize; - fMaxSize = maxSize; -} - -// AddArea -inline -void -BlockAllocator::AreaBucket::AddArea(Area *area) -{ - if (area) { - fAreas.Insert(area, area->NeedsDefragmenting()); - area->SetBucket(this); - D(SanityCheck(false)); - } -} - -// RemoveArea -inline -void -BlockAllocator::AreaBucket::RemoveArea(Area *area) -{ - if (area) { - fAreas.Remove(area); - area->SetBucket(NULL); - D(SanityCheck(false)); - } -} - -// GetNextArea -inline -Area * -BlockAllocator::AreaBucket::GetNextArea(Area* area) const -{ - return fAreas.GetNext(area); -} - -#endif // BA_DEFINE_INLINES - -#endif // BLOCK_ALLOCATOR_AREA_BUCKET_H diff --git a/src/add-ons/kernel/file_systems/ramfs/BlockAllocatorMisc.h b/src/add-ons/kernel/file_systems/ramfs/BlockAllocatorMisc.h deleted file mode 100644 index 117450c7de..0000000000 --- a/src/add-ons/kernel/file_systems/ramfs/BlockAllocatorMisc.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2007, Ingo Weinhold, ingo_weinhold@gmx.de. - * All rights reserved. Distributed under the terms of the MIT license. - */ -#ifndef BLOCK_ALLOCATOR_MISC_H -#define BLOCK_ALLOCATOR_MISC_H - -#include "Block.h" -#include "Misc.h" - -// block alignment -- start offsets and size -static const size_t kBlockAlignment = 4; // must be a power of 2 - -// block_align_{floor,ceil} -static inline size_t block_align_floor(size_t value) - { return value & ~(kBlockAlignment - 1); } -static inline size_t block_align_ceil(size_t value) - { return (value + kBlockAlignment - 1) & ~(kBlockAlignment - 1); } - -// minimal size of a gross/net block -// BAD DOG: No initializers in the kernel! -//static const size_t kMinBlockSize = block_align_ceil(sizeof(TFreeBlock)); -#define kMinBlockSize (block_align_ceil(sizeof(TFreeBlock))) -static const size_t kMinNetBlockSize = 8; - -static const size_t kDefragmentingTolerance = 10240; - -// bucket_containing_size -- bucket for to contain an area with size -static inline int bucket_containing_size(size_t size) - { return fls(size / kMinNetBlockSize) + 1; } - -// bucket_containing_min_size -- bucket containing areas >= size -static inline int -bucket_containing_min_size(size_t size) - { return (size ? bucket_containing_size(size - 1) + 1 : 0); } - - -#endif // BLOCK_ALLOCATOR_MISC_H diff --git a/src/add-ons/kernel/file_systems/ramfs/BlockReferenceManager.cpp b/src/add-ons/kernel/file_systems/ramfs/BlockReferenceManager.cpp deleted file mode 100644 index a1319daca1..0000000000 --- a/src/add-ons/kernel/file_systems/ramfs/BlockReferenceManager.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright 2007, Ingo Weinhold, ingo_weinhold@gmx.de. - * All rights reserved. Distributed under the terms of the MIT license. - */ - -#include "AllocationInfo.h" -#include "Block.h" -#include "BlockAllocator.h" // only for BA_PANIC -#include "BlockReferenceManager.h" -#include "DebugSupport.h" - -static const int kBlockReferenceTableSize = 128; - -// constructor -BlockReferenceManager::BlockReferenceManager() - : fTables(10), - fFreeList(NULL) -{ -} - -// destructor -BlockReferenceManager::~BlockReferenceManager() -{ -} - -// AllocateReference -BlockReference * -BlockReferenceManager::AllocateReference() -{ - BlockReference *reference = NULL; - if (!fFreeList) - _AddTable(); - if (fFreeList) { - reference = fFreeList; - fFreeList = *(BlockReference**)fFreeList; - } - return reference; -} - -// FreeReference -void -BlockReferenceManager::FreeReference(BlockReference *reference) -{ - if (reference) { - *(BlockReference**)reference = fFreeList; - fFreeList = reference; - } -} - -// CheckReference -bool -BlockReferenceManager::CheckReference(BlockReference *reference) -{ - if (reference) { - uint32 address = (addr_t)reference; - int32 tableCount = fTables.CountItems(); - for (int32 i = 0; i < tableCount; i++) { - Table *table = &fTables.ItemAt(i); - uint32 first = (addr_t)table->GetReferences(); - uint32 last = (addr_t)(table->GetReferences() + table->GetSize()); - if (first <= address && address < last) - return true; - } - } - FATAL("BlockReference %p does not exist!\n", reference); - BA_PANIC("BlockReference doesn't exist."); - return false; -} - -// GetAllocationInfo -void -BlockReferenceManager::GetAllocationInfo(AllocationInfo &info) -{ - info.AddListAllocation(fTables.GetCapacity(), sizeof(Table)); - int32 count = fTables.CountItems(); - for (int32 i = 0; i < count; i++) { - Table &table = fTables.ItemAt(i); - info.AddOtherAllocation(table.GetSize() * sizeof(BlockReference)); - } -} - -// _AddTable -status_t -BlockReferenceManager::_AddTable() -{ - status_t error = B_OK; - // add a new table - Table dummy; - if (fTables.AddItem(dummy)) { - int32 index = fTables.CountItems() - 1; - Table &table = fTables.ItemAt(index); - error = table.Init(kBlockReferenceTableSize); - if (error == B_OK) { - // add the references to the free list - uint32 count = table.GetSize(); - BlockReference *references = table.GetReferences(); - for (uint32 i = 0; i < count; i++) { - BlockReference *reference = references + i; - *(BlockReference**)reference = fFreeList; - fFreeList = reference; - } - } else - fTables.RemoveItem(index); - } else - SET_ERROR(error, B_NO_MEMORY); - return error; -} - - -// Table - -// destructor -BlockReferenceManager::Table::~Table() -{ - if (fReferences) - delete[] fReferences; -} - -// Init -status_t -BlockReferenceManager::Table::Init(int32 size) -{ - status_t error = (size > 0 ? B_OK : B_BAD_VALUE); - if (error == B_OK) { - fReferences = new(std::nothrow) BlockReference[size]; - if (fReferences) - fSize = size; - else - SET_ERROR(error, B_NO_MEMORY); - } - return error; -} - diff --git a/src/add-ons/kernel/file_systems/ramfs/BlockReferenceManager.h b/src/add-ons/kernel/file_systems/ramfs/BlockReferenceManager.h deleted file mode 100644 index 5bf7c1dfc7..0000000000 --- a/src/add-ons/kernel/file_systems/ramfs/BlockReferenceManager.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2007, Ingo Weinhold, ingo_weinhold@gmx.de. - * All rights reserved. Distributed under the terms of the MIT license. - */ -#ifndef BLOCK_REFERENCE_MANAGER_H -#define BLOCK_REFERENCE_MANAGER_H - -#include -#include "List.h" - -class AllocationInfo; -class BlockReference; - -class BlockReferenceManager { -public: - BlockReferenceManager(); - ~BlockReferenceManager(); - - BlockReference *AllocateReference(); - void FreeReference(BlockReference *reference); - - // debugging only - bool CheckReference(BlockReference *reference); - void GetAllocationInfo(AllocationInfo &info); - -private: - status_t _AddTable(); - -private: - class Table { - public: - Table() : fSize(0), fReferences(NULL) {} - Table(int) : fSize(0), fReferences(NULL) {} - ~Table(); - - status_t Init(int32 size); - - BlockReference *GetReferences() { return fReferences; } - - int32 GetSize() const { return fSize; } - - private: - uint32 fSize; - BlockReference *fReferences; - }; - - List fTables; - BlockReference *fFreeList; -}; - -#endif // BLOCK_REFERENCE_MANAGER_H -