* 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.
|
* Distributed under the terms of the NewOS License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "VMAnonymousCache.h"
|
#include "VMAnonymousCache.h"
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@@ -64,6 +65,7 @@
|
|||||||
#define SWAP_BLOCK_SHIFT 5 /* 1 << SWAP_BLOCK_SHIFT == SWAP_BLOCK_PAGES */
|
#define SWAP_BLOCK_SHIFT 5 /* 1 << SWAP_BLOCK_SHIFT == SWAP_BLOCK_PAGES */
|
||||||
#define SWAP_BLOCK_MASK (SWAP_BLOCK_PAGES - 1)
|
#define SWAP_BLOCK_MASK (SWAP_BLOCK_PAGES - 1)
|
||||||
|
|
||||||
|
|
||||||
struct swap_file : DoublyLinkedListLinkImpl<swap_file> {
|
struct swap_file : DoublyLinkedListLinkImpl<swap_file> {
|
||||||
int fd;
|
int fd;
|
||||||
struct vnode* vnode;
|
struct vnode* vnode;
|
||||||
@@ -97,7 +99,7 @@ struct SwapHashTableDefinition {
|
|||||||
{
|
{
|
||||||
off_t blockIndex = key.page_index >> SWAP_BLOCK_SHIFT;
|
off_t blockIndex = key.page_index >> SWAP_BLOCK_SHIFT;
|
||||||
VMAnonymousCache* cache = key.cache;
|
VMAnonymousCache* cache = key.cache;
|
||||||
return blockIndex ^ (int)(int *)cache;
|
return blockIndex ^ (size_t)(int*)cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Hash(const swap_block* value) const
|
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
|
status_t
|
||||||
VMAnonymousCache::Fault(struct VMAddressSpace* aspace, off_t offset)
|
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.
|
// Move all not shadowed pages from the source to the consumer cache.
|
||||||
|
|
||||||
for (VMCachePagesTree::Iterator it = source->pages.GetIterator();
|
_MergePagesSmallerSource(source);
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move all not shadowed swap pages from the source to the consumer cache.
|
// 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
|
// 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;
|
fAllocatedSwapSize += B_PAGE_SIZE * (off_t)sourceSwapBlock->used;
|
||||||
|
|
||||||
if (sourceSwapBlock->used == 0) {
|
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 -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -33,25 +33,28 @@ class VMAnonymousCache : public VMCache {
|
|||||||
public:
|
public:
|
||||||
virtual ~VMAnonymousCache();
|
virtual ~VMAnonymousCache();
|
||||||
|
|
||||||
status_t Init(bool canOvercommit, int32 numPrecommittedPages,
|
status_t Init(bool canOvercommit,
|
||||||
|
int32 numPrecommittedPages,
|
||||||
int32 numGuardPages);
|
int32 numGuardPages);
|
||||||
|
|
||||||
virtual status_t Commit(off_t size);
|
virtual status_t Commit(off_t size);
|
||||||
virtual bool HasPage(off_t offset);
|
virtual bool HasPage(off_t offset);
|
||||||
|
|
||||||
virtual status_t Read(off_t offset, const iovec *vecs, size_t count,
|
virtual status_t Read(off_t offset, const iovec* vecs,
|
||||||
uint32 flags, size_t *_numBytes);
|
size_t count, uint32 flags,
|
||||||
virtual status_t Write(off_t offset, const iovec *vecs, size_t count,
|
size_t* _numBytes);
|
||||||
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,
|
virtual status_t WriteAsync(off_t offset, const iovec* vecs,
|
||||||
size_t count, size_t numBytes, uint32 flags,
|
size_t count, size_t numBytes, uint32 flags,
|
||||||
AsyncIOCallback* callback);
|
AsyncIOCallback* callback);
|
||||||
virtual bool CanWritePage(off_t offset);
|
virtual bool CanWritePage(off_t offset);
|
||||||
|
|
||||||
virtual int32 MaxPagesPerAsyncWrite() const
|
virtual int32 MaxPagesPerAsyncWrite() const;
|
||||||
{ return 1; }
|
|
||||||
|
|
||||||
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);
|
virtual void Merge(VMCache* source);
|
||||||
|
|
||||||
@@ -65,6 +68,11 @@ private:
|
|||||||
swap_addr_t _SwapBlockGetAddress(off_t pageIndex);
|
swap_addr_t _SwapBlockGetAddress(off_t pageIndex);
|
||||||
status_t _Commit(off_t size);
|
status_t _Commit(off_t size);
|
||||||
|
|
||||||
|
void _MergePagesSmallerSource(
|
||||||
|
VMAnonymousCache* source);
|
||||||
|
void _MergePagesSmallerConsumer(
|
||||||
|
VMAnonymousCache* source);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend bool swap_free_page_swap_space(vm_page* page);
|
friend bool swap_free_page_swap_space(vm_page* page);
|
||||||
|
|
||||||
@@ -78,6 +86,8 @@ private:
|
|||||||
|
|
||||||
#endif // ENABLE_SWAP_SUPPORT
|
#endif // ENABLE_SWAP_SUPPORT
|
||||||
|
|
||||||
|
|
||||||
extern "C" void swap_get_info(struct system_memory_info* info);
|
extern "C" void swap_get_info(struct system_memory_info* info);
|
||||||
|
|
||||||
|
|
||||||
#endif /* _KERNEL_VM_STORE_ANONYMOUS_H */
|
#endif /* _KERNEL_VM_STORE_ANONYMOUS_H */
|
||||||
|
|||||||
Reference in New Issue
Block a user