* Some style cleanup.
* Pulled the code moving the pages out of Merge() into a separate method. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34778 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
* Distributed under the terms of the NewOS License.
|
||||
*/
|
||||
|
||||
|
||||
#include "VMAnonymousCache.h"
|
||||
|
||||
#include <errno.h>
|
||||
@@ -64,6 +65,7 @@
|
||||
#define SWAP_BLOCK_SHIFT 5 /* 1 << SWAP_BLOCK_SHIFT == SWAP_BLOCK_PAGES */
|
||||
#define SWAP_BLOCK_MASK (SWAP_BLOCK_PAGES - 1)
|
||||
|
||||
|
||||
struct swap_file : DoublyLinkedListLinkImpl<swap_file> {
|
||||
int fd;
|
||||
struct vnode* vnode;
|
||||
@@ -97,7 +99,7 @@ struct SwapHashTableDefinition {
|
||||
{
|
||||
off_t blockIndex = key.page_index >> SWAP_BLOCK_SHIFT;
|
||||
VMAnonymousCache* cache = key.cache;
|
||||
return blockIndex ^ (int)(int *)cache;
|
||||
return blockIndex ^ (size_t)(int*)cache;
|
||||
}
|
||||
|
||||
size_t Hash(const swap_block* value) const
|
||||
@@ -683,6 +685,13 @@ VMAnonymousCache::CanWritePage(off_t offset)
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
VMAnonymousCache::MaxPagesPerAsyncWrite() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
VMAnonymousCache::Fault(struct VMAddressSpace* aspace, off_t offset)
|
||||
{
|
||||
@@ -744,38 +753,7 @@ VMAnonymousCache::Merge(VMCache* _source)
|
||||
|
||||
// Move all not shadowed pages from the source to the consumer cache.
|
||||
|
||||
for (VMCachePagesTree::Iterator it = source->pages.GetIterator();
|
||||
vm_page* page = it.Next();) {
|
||||
// Note: Removing the current node while iterating through a
|
||||
// IteratableSplayTree is safe.
|
||||
vm_page* consumerPage = LookupPage(
|
||||
(off_t)page->cache_offset << PAGE_SHIFT);
|
||||
swap_addr_t consumerSwapSlot = _SwapBlockGetAddress(page->cache_offset);
|
||||
if (consumerPage == NULL && consumerSwapSlot == SWAP_SLOT_NONE) {
|
||||
// the page is not yet in the consumer cache - move it upwards
|
||||
source->RemovePage(page);
|
||||
InsertPage(page, (off_t)page->cache_offset << PAGE_SHIFT);
|
||||
|
||||
// If the moved-up page has a swap page associated, we mark it, so
|
||||
// that the swap page is moved upwards, too. We would lose if the
|
||||
// page was modified and written to swap, and is now not marked
|
||||
// modified.
|
||||
if (source->_SwapBlockGetAddress(page->cache_offset)
|
||||
!= SWAP_SLOT_NONE) {
|
||||
page->merge_swap = true;
|
||||
}
|
||||
#if DEBUG_PAGE_CACHE_TRANSITIONS
|
||||
} else {
|
||||
page->debug_flags = 0;
|
||||
if (consumerPage->state == PAGE_STATE_BUSY)
|
||||
page->debug_flags |= 0x1;
|
||||
if (consumerPage->type == PAGE_TYPE_DUMMY)
|
||||
page->debug_flags |= 0x2;
|
||||
page->collided_page = consumerPage;
|
||||
consumerPage->collided_page = page;
|
||||
#endif // DEBUG_PAGE_CACHE_TRANSITIONS
|
||||
}
|
||||
}
|
||||
_MergePagesSmallerSource(source);
|
||||
|
||||
// Move all not shadowed swap pages from the source to the consumer cache.
|
||||
|
||||
@@ -844,7 +822,7 @@ VMAnonymousCache::Merge(VMCache* _source)
|
||||
}
|
||||
|
||||
// All source swap pages that have not been freed yet are taken over by
|
||||
// by the consumer.
|
||||
// the consumer.
|
||||
fAllocatedSwapSize += B_PAGE_SIZE * (off_t)sourceSwapBlock->used;
|
||||
|
||||
if (sourceSwapBlock->used == 0) {
|
||||
@@ -1028,6 +1006,44 @@ VMAnonymousCache::_Commit(off_t size)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
VMAnonymousCache::_MergePagesSmallerSource(VMAnonymousCache* source)
|
||||
{
|
||||
for (VMCachePagesTree::Iterator it = source->pages.GetIterator();
|
||||
vm_page* page = it.Next();) {
|
||||
// Note: Removing the current node while iterating through a
|
||||
// IteratableSplayTree is safe.
|
||||
vm_page* consumerPage = LookupPage(
|
||||
(off_t)page->cache_offset << PAGE_SHIFT);
|
||||
swap_addr_t consumerSwapSlot = _SwapBlockGetAddress(page->cache_offset);
|
||||
if (consumerPage == NULL && consumerSwapSlot == SWAP_SLOT_NONE) {
|
||||
// the page is not yet in the consumer cache - move it upwards
|
||||
source->RemovePage(page);
|
||||
InsertPage(page, (off_t)page->cache_offset << PAGE_SHIFT);
|
||||
|
||||
// If the moved-up page has a swap page associated, we mark it, so
|
||||
// that the swap page is moved upwards, too. We would lose if the
|
||||
// page was modified and written to swap, and is now not marked
|
||||
// modified.
|
||||
if (source->_SwapBlockGetAddress(page->cache_offset)
|
||||
!= SWAP_SLOT_NONE) {
|
||||
page->merge_swap = true;
|
||||
}
|
||||
#if DEBUG_PAGE_CACHE_TRANSITIONS
|
||||
} else {
|
||||
page->debug_flags = 0;
|
||||
if (consumerPage->state == PAGE_STATE_BUSY)
|
||||
page->debug_flags |= 0x1;
|
||||
if (consumerPage->type == PAGE_TYPE_DUMMY)
|
||||
page->debug_flags |= 0x2;
|
||||
page->collided_page = consumerPage;
|
||||
consumerPage->collided_page = page;
|
||||
#endif // DEBUG_PAGE_CACHE_TRANSITIONS
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
|
||||
@@ -33,25 +33,28 @@ class VMAnonymousCache : public VMCache {
|
||||
public:
|
||||
virtual ~VMAnonymousCache();
|
||||
|
||||
status_t Init(bool canOvercommit, int32 numPrecommittedPages,
|
||||
status_t Init(bool canOvercommit,
|
||||
int32 numPrecommittedPages,
|
||||
int32 numGuardPages);
|
||||
|
||||
virtual status_t Commit(off_t size);
|
||||
virtual bool HasPage(off_t offset);
|
||||
|
||||
virtual status_t Read(off_t offset, const iovec *vecs, size_t count,
|
||||
uint32 flags, size_t *_numBytes);
|
||||
virtual status_t Write(off_t offset, const iovec *vecs, size_t count,
|
||||
uint32 flags, size_t *_numBytes);
|
||||
virtual status_t Read(off_t offset, const iovec* vecs,
|
||||
size_t count, uint32 flags,
|
||||
size_t* _numBytes);
|
||||
virtual status_t Write(off_t offset, const iovec* vecs,
|
||||
size_t count, uint32 flags,
|
||||
size_t* _numBytes);
|
||||
virtual status_t WriteAsync(off_t offset, const iovec* vecs,
|
||||
size_t count, size_t numBytes, uint32 flags,
|
||||
AsyncIOCallback* callback);
|
||||
virtual bool CanWritePage(off_t offset);
|
||||
|
||||
virtual int32 MaxPagesPerAsyncWrite() const
|
||||
{ return 1; }
|
||||
virtual int32 MaxPagesPerAsyncWrite() const;
|
||||
|
||||
virtual status_t Fault(struct VMAddressSpace* aspace, off_t offset);
|
||||
virtual status_t Fault(struct VMAddressSpace* aspace,
|
||||
off_t offset);
|
||||
|
||||
virtual void Merge(VMCache* source);
|
||||
|
||||
@@ -65,6 +68,11 @@ private:
|
||||
swap_addr_t _SwapBlockGetAddress(off_t pageIndex);
|
||||
status_t _Commit(off_t size);
|
||||
|
||||
void _MergePagesSmallerSource(
|
||||
VMAnonymousCache* source);
|
||||
void _MergePagesSmallerConsumer(
|
||||
VMAnonymousCache* source);
|
||||
|
||||
private:
|
||||
friend bool swap_free_page_swap_space(vm_page* page);
|
||||
|
||||
@@ -78,6 +86,8 @@ private:
|
||||
|
||||
#endif // ENABLE_SWAP_SUPPORT
|
||||
|
||||
|
||||
extern "C" void swap_get_info(struct system_memory_info* info);
|
||||
|
||||
|
||||
#endif /* _KERNEL_VM_STORE_ANONYMOUS_H */
|
||||
|
||||
Reference in New Issue
Block a user