* 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:
Ingo Weinhold
2010-07-10 15:08:13 +00:00
parent 61728e1e09
commit b944766870
10 changed files with 245 additions and 78 deletions
+48
View File
@@ -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
+32 -2
View File
@@ -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>