* Moved the vm_page initialization from vm_page.cpp:vm_page_init() to the new
vm_page::Init().
* Made vm_page::wired_count private and added accessor methods.
* Added VMCache::fWiredPagesCount (the number of wired pages the cache
contains) and accessor methods.
* Made more use of vm_page::IsMapped().
* vm_copy_on_write_area(): Added vm_page_reservation* parameter that can be
used to request a special handling for wired pages. If given the wired pages
are replaced by copies and the original pages are moved to the upper cache.
* vm_copy_area():
- We don't need to do any wired ranges handling, if the source area is a
B_SHARED_AREA, since we don't touch the area's mappings in this case.
- We no longer wait for wired ranges of the concerned areas to disappear.
Instead we use the new vm_copy_on_write_area() feature and just let it
copy the wired pages. This fixes #6288, an issue introduced with the use
of user mutexes in libroot: When executing multiple concurrent fork()s all
but the first one would wait on the fork mutex, which (being a user mutex)
would wire a page that the vm_copy_area() of the first fork() would wait
for.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@37460 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -101,6 +101,10 @@ public:
|
||||
void MovePage(vm_page* page);
|
||||
void MoveAllPages(VMCache* fromCache);
|
||||
|
||||
inline page_num_t WiredPagesCount() const;
|
||||
inline void IncrementWiredPagesCount();
|
||||
inline void DecrementWiredPagesCount();
|
||||
|
||||
void AddConsumer(VMCache* consumer);
|
||||
|
||||
status_t InsertAreaLocked(VMArea* area);
|
||||
@@ -197,6 +201,7 @@ private:
|
||||
PageEventWaiter* fPageEventWaiters;
|
||||
void* fUserData;
|
||||
VMCacheRef* fCacheRef;
|
||||
page_num_t fWiredPagesCount;
|
||||
};
|
||||
|
||||
|
||||
@@ -308,6 +313,49 @@ VMCache::MarkPageUnbusy(vm_page* page)
|
||||
}
|
||||
|
||||
|
||||
page_num_t
|
||||
VMCache::WiredPagesCount() const
|
||||
{
|
||||
return fWiredPagesCount;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
VMCache::IncrementWiredPagesCount()
|
||||
{
|
||||
ASSERT(fWiredPagesCount < page_count);
|
||||
|
||||
fWiredPagesCount++;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
VMCache::DecrementWiredPagesCount()
|
||||
{
|
||||
ASSERT(fWiredPagesCount > 0);
|
||||
|
||||
fWiredPagesCount--;
|
||||
}
|
||||
|
||||
|
||||
// vm_page methods implemented here to avoid VMCache.h inclusion in vm_types.h
|
||||
|
||||
inline void
|
||||
vm_page::IncrementWiredCount()
|
||||
{
|
||||
if (fWiredCount++ == 0)
|
||||
cache_ref->cache->IncrementWiredPagesCount();
|
||||
}
|
||||
|
||||
|
||||
inline void
|
||||
vm_page::DecrementWiredCount()
|
||||
{
|
||||
if (--fWiredCount == 0)
|
||||
cache_ref->cache->DecrementWiredPagesCount();
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#define _KERNEL_VM_VM_TYPES_H
|
||||
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <arch/vm_types.h>
|
||||
#include <condition_variable.h>
|
||||
#include <kernel.h>
|
||||
@@ -142,7 +144,8 @@ public:
|
||||
uint8 unused : 1;
|
||||
|
||||
uint8 usage_count;
|
||||
uint16 wired_count;
|
||||
|
||||
inline void Init(page_num_t pageNumber);
|
||||
|
||||
VMCacheRef* CacheRef() const { return cache_ref; }
|
||||
void SetCacheRef(VMCacheRef* cacheRef) { this->cache_ref = cacheRef; }
|
||||
@@ -151,11 +154,19 @@ public:
|
||||
{ return cache_ref != NULL ? cache_ref->cache : NULL; }
|
||||
|
||||
bool IsMapped() const
|
||||
{ return wired_count > 0 || !mappings.IsEmpty(); }
|
||||
{ return fWiredCount > 0 || !mappings.IsEmpty(); }
|
||||
|
||||
uint8 State() const { return state; }
|
||||
void InitState(uint8 newState);
|
||||
void SetState(uint8 newState);
|
||||
|
||||
inline uint16 WiredCount() const { return fWiredCount; }
|
||||
inline void IncrementWiredCount();
|
||||
inline void DecrementWiredCount();
|
||||
// both implemented in VMCache.h to avoid inclusion here
|
||||
|
||||
private:
|
||||
uint16 fWiredCount;
|
||||
};
|
||||
|
||||
|
||||
@@ -180,6 +191,25 @@ enum {
|
||||
#define VM_PAGE_ALLOC_BUSY 0x00000020
|
||||
|
||||
|
||||
inline void
|
||||
vm_page::Init(page_num_t pageNumber)
|
||||
{
|
||||
physical_page_number = pageNumber;
|
||||
InitState(PAGE_STATE_FREE);
|
||||
new(&mappings) vm_page_mappings();
|
||||
fWiredCount = 0;
|
||||
usage_count = 0;
|
||||
busy_writing = false;
|
||||
SetCacheRef(NULL);
|
||||
#if DEBUG_PAGE_QUEUE
|
||||
queue = NULL;
|
||||
#endif
|
||||
#if DEBUG_PAGE_ACCESS
|
||||
accessing_thread = -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if DEBUG_PAGE_ACCESS
|
||||
# include <thread.h>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user