1e50cf876SIngo Weinhold /*
2be7328a9SIngo Weinhold * Copyright 2008-2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3e50cf876SIngo Weinhold * Copyright 2003-2007, Axel Dörfler, axeld@pinc-software.de.
4e50cf876SIngo Weinhold * Distributed under the terms of the MIT License.
5e50cf876SIngo Weinhold *
6e50cf876SIngo Weinhold * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
7e50cf876SIngo Weinhold * Distributed under the terms of the NewOS License.
8e50cf876SIngo Weinhold */
9e50cf876SIngo Weinhold #ifndef _KERNEL_VM_VM_CACHE_H
10e50cf876SIngo Weinhold #define _KERNEL_VM_VM_CACHE_H
11e50cf876SIngo Weinhold
12e50cf876SIngo Weinhold
13355dc6beSIngo Weinhold #include <debug.h>
14e50cf876SIngo Weinhold #include <kernel.h>
15f8154d17SIngo Weinhold #include <util/DoublyLinkedList.h>
16e50cf876SIngo Weinhold #include <vm/vm.h>
17be7328a9SIngo Weinhold #include <vm/vm_types.h>
18be7328a9SIngo Weinhold
19be7328a9SIngo Weinhold #include "kernel_debug_config.h"
20e50cf876SIngo Weinhold
21e50cf876SIngo Weinhold
22e50cf876SIngo Weinhold struct kernel_args;
2330c9d3c0SAugustin Cavalier struct ObjectCache;
24e50cf876SIngo Weinhold
25e50cf876SIngo Weinhold
26be7328a9SIngo Weinhold enum {
27be7328a9SIngo Weinhold CACHE_TYPE_RAM = 0,
28be7328a9SIngo Weinhold CACHE_TYPE_VNODE,
29be7328a9SIngo Weinhold CACHE_TYPE_DEVICE,
30be7328a9SIngo Weinhold CACHE_TYPE_NULL
31be7328a9SIngo Weinhold };
32be7328a9SIngo Weinhold
33522c2f19SIngo Weinhold enum {
34522c2f19SIngo Weinhold PAGE_EVENT_NOT_BUSY = 0x01 // page not busy anymore
35522c2f19SIngo Weinhold };
36522c2f19SIngo Weinhold
37522c2f19SIngo Weinhold
38f8154d17SIngo Weinhold extern ObjectCache* gCacheRefObjectCache;
39f8154d17SIngo Weinhold extern ObjectCache* gAnonymousCacheObjectCache;
40f8154d17SIngo Weinhold extern ObjectCache* gAnonymousNoSwapCacheObjectCache;
41f8154d17SIngo Weinhold extern ObjectCache* gVnodeCacheObjectCache;
42f8154d17SIngo Weinhold extern ObjectCache* gDeviceCacheObjectCache;
43f8154d17SIngo Weinhold extern ObjectCache* gNullCacheObjectCache;
44f8154d17SIngo Weinhold
45f8154d17SIngo Weinhold
46be7328a9SIngo Weinhold struct VMCachePagesTreeDefinition {
47be7328a9SIngo Weinhold typedef page_num_t KeyType;
48be7328a9SIngo Weinhold typedef vm_page NodeType;
49be7328a9SIngo Weinhold
GetKeyVMCachePagesTreeDefinition50be7328a9SIngo Weinhold static page_num_t GetKey(const NodeType* node)
51be7328a9SIngo Weinhold {
52be7328a9SIngo Weinhold return node->cache_offset;
53be7328a9SIngo Weinhold }
54be7328a9SIngo Weinhold
GetLinkVMCachePagesTreeDefinition55be7328a9SIngo Weinhold static SplayTreeLink<NodeType>* GetLink(NodeType* node)
56be7328a9SIngo Weinhold {
57be7328a9SIngo Weinhold return &node->cache_link;
58be7328a9SIngo Weinhold }
59be7328a9SIngo Weinhold
CompareVMCachePagesTreeDefinition60be7328a9SIngo Weinhold static int Compare(page_num_t key, const NodeType* node)
61be7328a9SIngo Weinhold {
62be7328a9SIngo Weinhold return key == node->cache_offset ? 0
63be7328a9SIngo Weinhold : (key < node->cache_offset ? -1 : 1);
64be7328a9SIngo Weinhold }
65be7328a9SIngo Weinhold
GetListLinkVMCachePagesTreeDefinition66be7328a9SIngo Weinhold static NodeType** GetListLink(NodeType* node)
67be7328a9SIngo Weinhold {
68be7328a9SIngo Weinhold return &node->cache_next;
69be7328a9SIngo Weinhold }
70be7328a9SIngo Weinhold };
71be7328a9SIngo Weinhold
72be7328a9SIngo Weinhold typedef IteratableSplayTree<VMCachePagesTreeDefinition> VMCachePagesTree;
73be7328a9SIngo Weinhold
746379e53eSIngo Weinhold
75f8154d17SIngo Weinhold struct VMCache : public DoublyLinkedListLinkImpl<VMCache> {
76f8154d17SIngo Weinhold public:
77f8154d17SIngo Weinhold typedef DoublyLinkedList<VMCache> ConsumerList;
78f8154d17SIngo Weinhold
79be7328a9SIngo Weinhold public:
80be7328a9SIngo Weinhold VMCache();
81be7328a9SIngo Weinhold virtual ~VMCache();
82be7328a9SIngo Weinhold
83deee8524SIngo Weinhold status_t Init(uint32 cacheType, uint32 allocationFlags);
84be7328a9SIngo Weinhold
85be7328a9SIngo Weinhold virtual void Delete();
86be7328a9SIngo Weinhold
87355dc6beSIngo Weinhold inline bool Lock();
88355dc6beSIngo Weinhold inline bool TryLock();
89355dc6beSIngo Weinhold inline bool SwitchLock(mutex* from);
9077690f28SIngo Weinhold inline bool SwitchFromReadLock(rw_lock* from);
913632eeedSIngo Weinhold void Unlock(bool consumerLocked = false);
92355dc6beSIngo Weinhold inline void AssertLocked();
93be7328a9SIngo Weinhold
94355dc6beSIngo Weinhold inline void AcquireRefLocked();
95355dc6beSIngo Weinhold inline void AcquireRef();
96355dc6beSIngo Weinhold inline void ReleaseRefLocked();
97355dc6beSIngo Weinhold inline void ReleaseRef();
983632eeedSIngo Weinhold inline void ReleaseRefAndUnlock(
993632eeedSIngo Weinhold bool consumerLocked = false);
100be7328a9SIngo Weinhold
CacheRefVMCache101cf99b9abSIngo Weinhold inline VMCacheRef* CacheRef() const { return fCacheRef; }
102cf99b9abSIngo Weinhold
103522c2f19SIngo Weinhold void WaitForPageEvents(vm_page* page, uint32 events,
104522c2f19SIngo Weinhold bool relock);
NotifyPageEventsVMCache105522c2f19SIngo Weinhold void NotifyPageEvents(vm_page* page, uint32 events)
106522c2f19SIngo Weinhold { if (fPageEventWaiters != NULL)
107522c2f19SIngo Weinhold _NotifyPageEvents(page, events); }
10872382fa6SIngo Weinhold inline void MarkPageUnbusy(vm_page* page);
109522c2f19SIngo Weinhold
110be7328a9SIngo Weinhold vm_page* LookupPage(off_t offset);
111be7328a9SIngo Weinhold void InsertPage(vm_page* page, off_t offset);
112be7328a9SIngo Weinhold void RemovePage(vm_page* page);
113c6657ffeSHamish Morrison void MovePage(vm_page* page, off_t offset);
114eb8dc1ebSIngo Weinhold void MovePage(vm_page* page);
115eb8dc1ebSIngo Weinhold void MoveAllPages(VMCache* fromCache);
116be7328a9SIngo Weinhold
117b9447668SIngo Weinhold inline page_num_t WiredPagesCount() const;
118b9447668SIngo Weinhold inline void IncrementWiredPagesCount();
119b9447668SIngo Weinhold inline void DecrementWiredPagesCount();
120b9447668SIngo Weinhold
GuardSizeVMCache121d1f280c8SHamish Morrison virtual int32 GuardSize() { return 0; }
122d1f280c8SHamish Morrison
123be7328a9SIngo Weinhold void AddConsumer(VMCache* consumer);
124be7328a9SIngo Weinhold
125be7328a9SIngo Weinhold status_t InsertAreaLocked(VMArea* area);
126be7328a9SIngo Weinhold status_t RemoveArea(VMArea* area);
1272e74d74fSIngo Weinhold void TransferAreas(VMCache* fromCache);
1282e74d74fSIngo Weinhold uint32 CountWritableAreas(VMArea* ignoreArea) const;
129be7328a9SIngo Weinhold
130be7328a9SIngo Weinhold status_t WriteModified();
131cff6e9e4SIngo Weinhold status_t SetMinimalCommitment(off_t commitment,
132cff6e9e4SIngo Weinhold int priority);
133efeca209SIngo Weinhold virtual status_t Resize(off_t newSize, int priority);
134c6657ffeSHamish Morrison virtual status_t Rebase(off_t newBase, int priority);
1354e2b49bcSMichael Lotz virtual status_t Adopt(VMCache* source, off_t offset, off_t size,
1364e2b49bcSMichael Lotz off_t newOffset);
137be7328a9SIngo Weinhold
1388e74e307SMichael Lotz virtual status_t Discard(off_t offset, off_t size);
1398e74e307SMichael Lotz
140be7328a9SIngo Weinhold status_t FlushAndRemoveAllPages();
141be7328a9SIngo Weinhold
UserDataVMCache1423632eeedSIngo Weinhold void* UserData() { return fUserData; }
SetUserDataVMCache1433632eeedSIngo Weinhold void SetUserData(void* data) { fUserData = data; }
1443632eeedSIngo Weinhold // Settable by the lock owner and valid as
1453632eeedSIngo Weinhold // long as the lock is owned.
1463632eeedSIngo Weinhold
147be7328a9SIngo Weinhold // for debugging only
RefCountVMCache148be7328a9SIngo Weinhold int32 RefCount() const
149be7328a9SIngo Weinhold { return fRefCount; }
150be7328a9SIngo Weinhold
151be7328a9SIngo Weinhold // backing store operations
152cff6e9e4SIngo Weinhold virtual status_t Commit(off_t size, int priority);
153be7328a9SIngo Weinhold virtual bool HasPage(off_t offset);
154be7328a9SIngo Weinhold
155435c43f5SIngo Weinhold virtual status_t Read(off_t offset, const generic_io_vec *vecs,
1566440406aSIngo Weinhold size_t count, uint32 flags,
157435c43f5SIngo Weinhold generic_size_t *_numBytes);
158435c43f5SIngo Weinhold virtual status_t Write(off_t offset, const generic_io_vec *vecs,
159435c43f5SIngo Weinhold size_t count, uint32 flags,
160435c43f5SIngo Weinhold generic_size_t *_numBytes);
161435c43f5SIngo Weinhold virtual status_t WriteAsync(off_t offset,
162435c43f5SIngo Weinhold const generic_io_vec* vecs, size_t count,
163435c43f5SIngo Weinhold generic_size_t numBytes, uint32 flags,
164be7328a9SIngo Weinhold AsyncIOCallback* callback);
165be7328a9SIngo Weinhold virtual bool CanWritePage(off_t offset);
166be7328a9SIngo Weinhold
MaxPagesPerWriteVMCache167be7328a9SIngo Weinhold virtual int32 MaxPagesPerWrite() const
168be7328a9SIngo Weinhold { return -1; } // no restriction
MaxPagesPerAsyncWriteVMCache169be7328a9SIngo Weinhold virtual int32 MaxPagesPerAsyncWrite() const
170be7328a9SIngo Weinhold { return -1; } // no restriction
171be7328a9SIngo Weinhold
172be7328a9SIngo Weinhold virtual status_t Fault(struct VMAddressSpace *aspace,
173be7328a9SIngo Weinhold off_t offset);
174be7328a9SIngo Weinhold
175be7328a9SIngo Weinhold virtual void Merge(VMCache* source);
176be7328a9SIngo Weinhold
177be7328a9SIngo Weinhold virtual status_t AcquireUnreferencedStoreRef();
178be7328a9SIngo Weinhold virtual void AcquireStoreRef();
179be7328a9SIngo Weinhold virtual void ReleaseStoreRef();
180be7328a9SIngo Weinhold
18186875ad9SIngo Weinhold virtual bool DebugHasPage(off_t offset);
18286875ad9SIngo Weinhold vm_page* DebugLookupPage(off_t offset);
18386875ad9SIngo Weinhold
184f8e263c1SIngo Weinhold virtual void Dump(bool showPages) const;
185f8e263c1SIngo Weinhold
186f8154d17SIngo Weinhold protected:
187f8154d17SIngo Weinhold virtual void DeleteObject() = 0;
188f8154d17SIngo Weinhold
189be7328a9SIngo Weinhold public:
1906440406aSIngo Weinhold VMArea* areas;
191f8154d17SIngo Weinhold ConsumerList consumers;
192be7328a9SIngo Weinhold // list of caches that use this cache as a source
193be7328a9SIngo Weinhold VMCachePagesTree pages;
194be7328a9SIngo Weinhold VMCache* source;
195be7328a9SIngo Weinhold off_t virtual_base;
196be7328a9SIngo Weinhold off_t virtual_end;
197be7328a9SIngo Weinhold off_t committed_size;
198be7328a9SIngo Weinhold // TODO: Remove!
199be7328a9SIngo Weinhold uint32 page_count;
200be7328a9SIngo Weinhold uint32 temporary : 1;
201*a8877df1SAugustin Cavalier uint32 unmergeable : 1;
202be7328a9SIngo Weinhold uint32 type : 6;
203be7328a9SIngo Weinhold
204be7328a9SIngo Weinhold #if DEBUG_CACHE_LIST
2056440406aSIngo Weinhold VMCache* debug_previous;
2066440406aSIngo Weinhold VMCache* debug_next;
207be7328a9SIngo Weinhold #endif
208be7328a9SIngo Weinhold
209be7328a9SIngo Weinhold private:
210522c2f19SIngo Weinhold struct PageEventWaiter;
2116379e53eSIngo Weinhold friend struct VMCacheRef;
212522c2f19SIngo Weinhold
213522c2f19SIngo Weinhold private:
214522c2f19SIngo Weinhold void _NotifyPageEvents(vm_page* page, uint32 events);
215522c2f19SIngo Weinhold
2166440406aSIngo Weinhold inline bool _IsMergeable() const;
2176440406aSIngo Weinhold
218a0d93d14SIngo Weinhold void _MergeWithOnlyConsumer();
2196440406aSIngo Weinhold void _RemoveConsumer(VMCache* consumer);
2206440406aSIngo Weinhold
221428bc69aSMichael Lotz bool _FreePageRange(VMCachePagesTree::Iterator it,
222428bc69aSMichael Lotz page_num_t* toPage);
223428bc69aSMichael Lotz
2246440406aSIngo Weinhold private:
225be7328a9SIngo Weinhold int32 fRefCount;
226be7328a9SIngo Weinhold mutex fLock;
227522c2f19SIngo Weinhold PageEventWaiter* fPageEventWaiters;
2283632eeedSIngo Weinhold void* fUserData;
2296379e53eSIngo Weinhold VMCacheRef* fCacheRef;
230b9447668SIngo Weinhold page_num_t fWiredPagesCount;
231be7328a9SIngo Weinhold };
232be7328a9SIngo Weinhold
233be7328a9SIngo Weinhold
234be7328a9SIngo Weinhold #if DEBUG_CACHE_LIST
235be7328a9SIngo Weinhold extern VMCache* gDebugCacheList;
236be7328a9SIngo Weinhold #endif
237be7328a9SIngo Weinhold
238be7328a9SIngo Weinhold
239be7328a9SIngo Weinhold class VMCacheFactory {
240be7328a9SIngo Weinhold public:
241be7328a9SIngo Weinhold static status_t CreateAnonymousCache(VMCache*& cache,
242be7328a9SIngo Weinhold bool canOvercommit, int32 numPrecommittedPages,
243cff6e9e4SIngo Weinhold int32 numGuardPages, bool swappable,
244cff6e9e4SIngo Weinhold int priority);
245be7328a9SIngo Weinhold static status_t CreateVnodeCache(VMCache*& cache,
246be7328a9SIngo Weinhold struct vnode* vnode);
247be7328a9SIngo Weinhold static status_t CreateDeviceCache(VMCache*& cache,
248be7328a9SIngo Weinhold addr_t baseAddress);
249cff6e9e4SIngo Weinhold static status_t CreateNullCache(int priority, VMCache*& cache);
250be7328a9SIngo Weinhold };
251be7328a9SIngo Weinhold
252be7328a9SIngo Weinhold
253355dc6beSIngo Weinhold
254355dc6beSIngo Weinhold bool
Lock()255355dc6beSIngo Weinhold VMCache::Lock()
256355dc6beSIngo Weinhold {
257355dc6beSIngo Weinhold return mutex_lock(&fLock) == B_OK;
258355dc6beSIngo Weinhold }
259355dc6beSIngo Weinhold
260355dc6beSIngo Weinhold
261355dc6beSIngo Weinhold bool
TryLock()262355dc6beSIngo Weinhold VMCache::TryLock()
263355dc6beSIngo Weinhold {
264355dc6beSIngo Weinhold return mutex_trylock(&fLock) == B_OK;
265355dc6beSIngo Weinhold }
266355dc6beSIngo Weinhold
267355dc6beSIngo Weinhold
268355dc6beSIngo Weinhold bool
SwitchLock(mutex * from)269355dc6beSIngo Weinhold VMCache::SwitchLock(mutex* from)
270355dc6beSIngo Weinhold {
271355dc6beSIngo Weinhold return mutex_switch_lock(from, &fLock) == B_OK;
272355dc6beSIngo Weinhold }
273355dc6beSIngo Weinhold
274355dc6beSIngo Weinhold
27577690f28SIngo Weinhold bool
SwitchFromReadLock(rw_lock * from)27677690f28SIngo Weinhold VMCache::SwitchFromReadLock(rw_lock* from)
27777690f28SIngo Weinhold {
27877690f28SIngo Weinhold return mutex_switch_from_read_lock(from, &fLock) == B_OK;
27977690f28SIngo Weinhold }
28077690f28SIngo Weinhold
28177690f28SIngo Weinhold
282355dc6beSIngo Weinhold void
AssertLocked()283355dc6beSIngo Weinhold VMCache::AssertLocked()
284355dc6beSIngo Weinhold {
285355dc6beSIngo Weinhold ASSERT_LOCKED_MUTEX(&fLock);
286355dc6beSIngo Weinhold }
287355dc6beSIngo Weinhold
288355dc6beSIngo Weinhold
289355dc6beSIngo Weinhold void
AcquireRefLocked()290355dc6beSIngo Weinhold VMCache::AcquireRefLocked()
291355dc6beSIngo Weinhold {
292355dc6beSIngo Weinhold ASSERT_LOCKED_MUTEX(&fLock);
293355dc6beSIngo Weinhold
294355dc6beSIngo Weinhold fRefCount++;
295355dc6beSIngo Weinhold }
296355dc6beSIngo Weinhold
297355dc6beSIngo Weinhold
298355dc6beSIngo Weinhold void
AcquireRef()299355dc6beSIngo Weinhold VMCache::AcquireRef()
300355dc6beSIngo Weinhold {
301355dc6beSIngo Weinhold Lock();
302355dc6beSIngo Weinhold fRefCount++;
303355dc6beSIngo Weinhold Unlock();
304355dc6beSIngo Weinhold }
305355dc6beSIngo Weinhold
306355dc6beSIngo Weinhold
307355dc6beSIngo Weinhold void
ReleaseRefLocked()308355dc6beSIngo Weinhold VMCache::ReleaseRefLocked()
309355dc6beSIngo Weinhold {
310355dc6beSIngo Weinhold ASSERT_LOCKED_MUTEX(&fLock);
311355dc6beSIngo Weinhold
312355dc6beSIngo Weinhold fRefCount--;
313355dc6beSIngo Weinhold }
314355dc6beSIngo Weinhold
315355dc6beSIngo Weinhold
316355dc6beSIngo Weinhold void
ReleaseRef()317355dc6beSIngo Weinhold VMCache::ReleaseRef()
318355dc6beSIngo Weinhold {
319355dc6beSIngo Weinhold Lock();
320355dc6beSIngo Weinhold fRefCount--;
321355dc6beSIngo Weinhold Unlock();
322355dc6beSIngo Weinhold }
323355dc6beSIngo Weinhold
324355dc6beSIngo Weinhold
325355dc6beSIngo Weinhold void
ReleaseRefAndUnlock(bool consumerLocked)3263632eeedSIngo Weinhold VMCache::ReleaseRefAndUnlock(bool consumerLocked)
327355dc6beSIngo Weinhold {
328355dc6beSIngo Weinhold ReleaseRefLocked();
3293632eeedSIngo Weinhold Unlock(consumerLocked);
330355dc6beSIngo Weinhold }
331355dc6beSIngo Weinhold
332355dc6beSIngo Weinhold
33372382fa6SIngo Weinhold void
MarkPageUnbusy(vm_page * page)33472382fa6SIngo Weinhold VMCache::MarkPageUnbusy(vm_page* page)
33572382fa6SIngo Weinhold {
3364bb4f793SIngo Weinhold ASSERT(page->busy);
33772382fa6SIngo Weinhold page->busy = false;
33872382fa6SIngo Weinhold NotifyPageEvents(page, PAGE_EVENT_NOT_BUSY);
33972382fa6SIngo Weinhold }
34072382fa6SIngo Weinhold
34172382fa6SIngo Weinhold
342b9447668SIngo Weinhold page_num_t
WiredPagesCount()343b9447668SIngo Weinhold VMCache::WiredPagesCount() const
344b9447668SIngo Weinhold {
345b9447668SIngo Weinhold return fWiredPagesCount;
346b9447668SIngo Weinhold }
347b9447668SIngo Weinhold
348b9447668SIngo Weinhold
349b9447668SIngo Weinhold void
IncrementWiredPagesCount()350b9447668SIngo Weinhold VMCache::IncrementWiredPagesCount()
351b9447668SIngo Weinhold {
352b9447668SIngo Weinhold ASSERT(fWiredPagesCount < page_count);
353b9447668SIngo Weinhold
354b9447668SIngo Weinhold fWiredPagesCount++;
355b9447668SIngo Weinhold }
356b9447668SIngo Weinhold
357b9447668SIngo Weinhold
358b9447668SIngo Weinhold void
DecrementWiredPagesCount()359b9447668SIngo Weinhold VMCache::DecrementWiredPagesCount()
360b9447668SIngo Weinhold {
361b9447668SIngo Weinhold ASSERT(fWiredPagesCount > 0);
362b9447668SIngo Weinhold
363b9447668SIngo Weinhold fWiredPagesCount--;
364b9447668SIngo Weinhold }
365b9447668SIngo Weinhold
366b9447668SIngo Weinhold
367b9447668SIngo Weinhold // vm_page methods implemented here to avoid VMCache.h inclusion in vm_types.h
368b9447668SIngo Weinhold
369b9447668SIngo Weinhold inline void
IncrementWiredCount()370b9447668SIngo Weinhold vm_page::IncrementWiredCount()
371b9447668SIngo Weinhold {
372b9447668SIngo Weinhold if (fWiredCount++ == 0)
373b9447668SIngo Weinhold cache_ref->cache->IncrementWiredPagesCount();
374b9447668SIngo Weinhold }
375b9447668SIngo Weinhold
376b9447668SIngo Weinhold
377b9447668SIngo Weinhold inline void
DecrementWiredCount()378b9447668SIngo Weinhold vm_page::DecrementWiredCount()
379b9447668SIngo Weinhold {
3808ca0f03dSX512 ASSERT_PRINT(fWiredCount > 0, "page: %#" B_PRIx64, physical_page_number * B_PAGE_SIZE);
3812cdd33d4SMichael Lotz
382b9447668SIngo Weinhold if (--fWiredCount == 0)
383b9447668SIngo Weinhold cache_ref->cache->DecrementWiredPagesCount();
384b9447668SIngo Weinhold }
385b9447668SIngo Weinhold
386b9447668SIngo Weinhold
387e50cf876SIngo Weinhold #ifdef __cplusplus
388e50cf876SIngo Weinhold extern "C" {
389e50cf876SIngo Weinhold #endif
390e50cf876SIngo Weinhold
391e50cf876SIngo Weinhold status_t vm_cache_init(struct kernel_args *args);
3922e74d74fSIngo Weinhold void vm_cache_init_post_heap();
393e50cf876SIngo Weinhold struct VMCache *vm_cache_acquire_locked_page_cache(struct vm_page *page,
394e50cf876SIngo Weinhold bool dontWait);
395e50cf876SIngo Weinhold
396e50cf876SIngo Weinhold #ifdef __cplusplus
397e50cf876SIngo Weinhold }
398e50cf876SIngo Weinhold #endif
399e50cf876SIngo Weinhold
400be7328a9SIngo Weinhold
401e50cf876SIngo Weinhold #endif /* _KERNEL_VM_VM_CACHE_H */
402