diff --git a/headers/private/kernel/vm/VMCache.h b/headers/private/kernel/vm/VMCache.h index fcf87c98fb..a84eb099fc 100644 --- a/headers/private/kernel/vm/VMCache.h +++ b/headers/private/kernel/vm/VMCache.h @@ -1,4 +1,5 @@ /* + * Copyright 2008-2009, Ingo Weinhold, ingo_weinhold@gmx.de. * Copyright 2003-2007, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. * @@ -11,11 +12,175 @@ #include #include +#include + +#include "kernel_debug_config.h" struct kernel_args; +enum { + CACHE_TYPE_RAM = 0, + CACHE_TYPE_VNODE, + CACHE_TYPE_DEVICE, + CACHE_TYPE_NULL +}; + +struct VMCachePagesTreeDefinition { + typedef page_num_t KeyType; + typedef vm_page NodeType; + + static page_num_t GetKey(const NodeType* node) + { + return node->cache_offset; + } + + static SplayTreeLink* GetLink(NodeType* node) + { + return &node->cache_link; + } + + static int Compare(page_num_t key, const NodeType* node) + { + return key == node->cache_offset ? 0 + : (key < node->cache_offset ? -1 : 1); + } + + static NodeType** GetListLink(NodeType* node) + { + return &node->cache_next; + } +}; + +typedef IteratableSplayTree VMCachePagesTree; + +struct VMCache { +public: + VMCache(); + virtual ~VMCache(); + + status_t Init(uint32 cacheType); + + virtual void Delete(); + + bool Lock() + { return mutex_lock(&fLock) == B_OK; } + bool TryLock() + { return mutex_trylock(&fLock) == B_OK; } + bool SwitchLock(mutex* from) + { return mutex_switch_lock(from, &fLock) + == B_OK; } + void Unlock(); + void AssertLocked() + { ASSERT_LOCKED_MUTEX(&fLock); } + + void AcquireRefLocked(); + void AcquireRef(); + void ReleaseRefLocked(); + void ReleaseRef(); + void ReleaseRefAndUnlock() + { ReleaseRefLocked(); Unlock(); } + + vm_page* LookupPage(off_t offset); + void InsertPage(vm_page* page, off_t offset); + void RemovePage(vm_page* page); + + void AddConsumer(VMCache* consumer); + + status_t InsertAreaLocked(VMArea* area); + status_t RemoveArea(VMArea* area); + + status_t WriteModified(); + status_t SetMinimalCommitment(off_t commitment); + status_t Resize(off_t newSize); + + status_t FlushAndRemoveAllPages(); + + // for debugging only + mutex* GetLock() + { return &fLock; } + int32 RefCount() const + { return fRefCount; } + + // backing store operations + 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 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 MaxPagesPerWrite() const + { return -1; } // no restriction + virtual int32 MaxPagesPerAsyncWrite() const + { return -1; } // no restriction + + virtual status_t Fault(struct VMAddressSpace *aspace, + off_t offset); + + virtual void Merge(VMCache* source); + + virtual status_t AcquireUnreferencedStoreRef(); + virtual void AcquireStoreRef(); + virtual void ReleaseStoreRef(); + +private: + inline bool _IsMergeable() const; + + void _MergeWithOnlyConsumer(); + void _RemoveConsumer(VMCache* consumer); + +public: + struct VMArea* areas; + struct list_link consumer_link; + struct list consumers; + // list of caches that use this cache as a source + VMCachePagesTree pages; + VMCache* source; + off_t virtual_base; + off_t virtual_end; + off_t committed_size; + // TODO: Remove! + uint32 page_count; + uint32 temporary : 1; + uint32 scan_skip : 1; + uint32 type : 6; + +#if DEBUG_CACHE_LIST + struct VMCache* debug_previous; + struct VMCache* debug_next; +#endif + +private: + int32 fRefCount; + mutex fLock; +}; + + +#if DEBUG_CACHE_LIST +extern VMCache* gDebugCacheList; +#endif + + +class VMCacheFactory { +public: + static status_t CreateAnonymousCache(VMCache*& cache, + bool canOvercommit, int32 numPrecommittedPages, + int32 numGuardPages, bool swappable); + static status_t CreateVnodeCache(VMCache*& cache, + struct vnode* vnode); + static status_t CreateDeviceCache(VMCache*& cache, + addr_t baseAddress); + static status_t CreateNullCache(VMCache*& cache); +}; + + #ifdef __cplusplus extern "C" { #endif @@ -28,4 +193,5 @@ struct VMCache *vm_cache_acquire_locked_page_cache(struct vm_page *page, } #endif + #endif /* _KERNEL_VM_VM_CACHE_H */ diff --git a/headers/private/kernel/vm/vm_types.h b/headers/private/kernel/vm/vm_types.h index b3abf4397f..102d6bc5b0 100644 --- a/headers/private/kernel/vm/vm_types.h +++ b/headers/private/kernel/vm/vm_types.h @@ -125,166 +125,5 @@ enum { PAGE_STATE_UNUSED }; -enum { - CACHE_TYPE_RAM = 0, - CACHE_TYPE_VNODE, - CACHE_TYPE_DEVICE, - CACHE_TYPE_NULL -}; - -struct VMCachePagesTreeDefinition { - typedef page_num_t KeyType; - typedef vm_page NodeType; - - static page_num_t GetKey(const NodeType* node) - { - return node->cache_offset; - } - - static SplayTreeLink* GetLink(NodeType* node) - { - return &node->cache_link; - } - - static int Compare(page_num_t key, const NodeType* node) - { - return key == node->cache_offset ? 0 - : (key < node->cache_offset ? -1 : 1); - } - - static NodeType** GetListLink(NodeType* node) - { - return &node->cache_next; - } -}; - -typedef IteratableSplayTree VMCachePagesTree; - -struct VMCache { -public: - VMCache(); - virtual ~VMCache(); - - status_t Init(uint32 cacheType); - - virtual void Delete(); - - bool Lock() - { return mutex_lock(&fLock) == B_OK; } - bool TryLock() - { return mutex_trylock(&fLock) == B_OK; } - bool SwitchLock(mutex* from) - { return mutex_switch_lock(from, &fLock) - == B_OK; } - void Unlock(); - void AssertLocked() - { ASSERT_LOCKED_MUTEX(&fLock); } - - void AcquireRefLocked(); - void AcquireRef(); - void ReleaseRefLocked(); - void ReleaseRef(); - void ReleaseRefAndUnlock() - { ReleaseRefLocked(); Unlock(); } - - vm_page* LookupPage(off_t offset); - void InsertPage(vm_page* page, off_t offset); - void RemovePage(vm_page* page); - - void AddConsumer(VMCache* consumer); - - status_t InsertAreaLocked(VMArea* area); - status_t RemoveArea(VMArea* area); - - status_t WriteModified(); - status_t SetMinimalCommitment(off_t commitment); - status_t Resize(off_t newSize); - - status_t FlushAndRemoveAllPages(); - - // for debugging only - mutex* GetLock() - { return &fLock; } - int32 RefCount() const - { return fRefCount; } - - // backing store operations - 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 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 MaxPagesPerWrite() const - { return -1; } // no restriction - virtual int32 MaxPagesPerAsyncWrite() const - { return -1; } // no restriction - - virtual status_t Fault(struct VMAddressSpace *aspace, - off_t offset); - - virtual void Merge(VMCache* source); - - virtual status_t AcquireUnreferencedStoreRef(); - virtual void AcquireStoreRef(); - virtual void ReleaseStoreRef(); - -private: - inline bool _IsMergeable() const; - - void _MergeWithOnlyConsumer(); - void _RemoveConsumer(VMCache* consumer); - - -public: - struct VMArea* areas; - struct list_link consumer_link; - struct list consumers; - // list of caches that use this cache as a source - VMCachePagesTree pages; - VMCache* source; - off_t virtual_base; - off_t virtual_end; - off_t committed_size; - // TODO: Remove! - uint32 page_count; - uint32 temporary : 1; - uint32 scan_skip : 1; - uint32 type : 6; - -#if DEBUG_CACHE_LIST - struct VMCache* debug_previous; - struct VMCache* debug_next; -#endif - -private: - int32 fRefCount; - mutex fLock; -}; - - -#if DEBUG_CACHE_LIST -extern VMCache* gDebugCacheList; -#endif - - -class VMCacheFactory { -public: - static status_t CreateAnonymousCache(VMCache*& cache, - bool canOvercommit, int32 numPrecommittedPages, - int32 numGuardPages, bool swappable); - static status_t CreateVnodeCache(VMCache*& cache, - struct vnode* vnode); - static status_t CreateDeviceCache(VMCache*& cache, - addr_t baseAddress); - static status_t CreateNullCache(VMCache*& cache); -}; - #endif // _KERNEL_VM_VM_TYPES_H diff --git a/src/system/kernel/cache/vnode_store.h b/src/system/kernel/cache/vnode_store.h index 50780c6c02..e51c8f2601 100644 --- a/src/system/kernel/cache/vnode_store.h +++ b/src/system/kernel/cache/vnode_store.h @@ -1,5 +1,5 @@ /* - * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2008-2009, Ingo Weinhold, ingo_weinhold@gmx.de. * Copyright 2004-2007, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. */ @@ -7,7 +7,7 @@ #define VNODE_STORE_H -#include +#include struct file_cache_ref; diff --git a/src/system/kernel/vm/VMAddressSpace.cpp b/src/system/kernel/vm/VMAddressSpace.cpp index 4479b90121..492ccf24d4 100644 --- a/src/system/kernel/vm/VMAddressSpace.cpp +++ b/src/system/kernel/vm/VMAddressSpace.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include "VMKernelAddressSpace.h" #include "VMUserAddressSpace.h" diff --git a/src/system/kernel/vm/VMAnonymousCache.h b/src/system/kernel/vm/VMAnonymousCache.h index 5620e0cf69..f4dfa1093e 100644 --- a/src/system/kernel/vm/VMAnonymousCache.h +++ b/src/system/kernel/vm/VMAnonymousCache.h @@ -1,5 +1,5 @@ /* - * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2008-2009, Ingo Weinhold, ingo_weinhold@gmx.de. * Copyright 2004-2008, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. * @@ -9,7 +9,8 @@ #ifndef _KERNEL_VM_STORE_ANONYMOUS_H #define _KERNEL_VM_STORE_ANONYMOUS_H -#include + +#include #if ENABLE_SWAP_SUPPORT diff --git a/src/system/kernel/vm/VMAnonymousNoSwapCache.h b/src/system/kernel/vm/VMAnonymousNoSwapCache.h index 84dfb5ed23..ec9e2b1c09 100644 --- a/src/system/kernel/vm/VMAnonymousNoSwapCache.h +++ b/src/system/kernel/vm/VMAnonymousNoSwapCache.h @@ -1,5 +1,5 @@ /* - * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2008-2009, Ingo Weinhold, ingo_weinhold@gmx.de. * Copyright 2004-2007, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. * @@ -9,7 +9,8 @@ #ifndef _KERNEL_VM_STORE_ANONYMOUS_NO_SWAP_H #define _KERNEL_VM_STORE_ANONYMOUS_NO_SWAP_H -#include + +#include class VMAnonymousNoSwapCache : public VMCache { diff --git a/src/system/kernel/vm/VMDeviceCache.h b/src/system/kernel/vm/VMDeviceCache.h index fa11c3594d..7502c91a55 100644 --- a/src/system/kernel/vm/VMDeviceCache.h +++ b/src/system/kernel/vm/VMDeviceCache.h @@ -1,5 +1,5 @@ /* - * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2008-2009, Ingo Weinhold, ingo_weinhold@gmx.de. * Copyright 2005-2007, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. * @@ -9,7 +9,8 @@ #ifndef _KERNEL_VM_STORE_DEVICE_H #define _KERNEL_VM_STORE_DEVICE_H -#include + +#include class VMDeviceCache : public VMCache { diff --git a/src/system/kernel/vm/VMNullCache.h b/src/system/kernel/vm/VMNullCache.h index 7622e77fc7..96a0cf222e 100644 --- a/src/system/kernel/vm/VMNullCache.h +++ b/src/system/kernel/vm/VMNullCache.h @@ -1,5 +1,5 @@ /* - * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2008-2009, Ingo Weinhold, ingo_weinhold@gmx.de. * Copyright 2005-2007, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. * @@ -9,7 +9,8 @@ #ifndef _KERNEL_VM_STORE_NULL_H #define _KERNEL_VM_STORE_NULL_H -#include + +#include class VMNullCache : public VMCache {