* Added some more asserts for cached pages.

* full_scan_inactive_pages(): Fixed syntactical glitch (missing "else").
  Affected only the active paging mode and was relatively harmless. The worst
  case would be that an inactive page would be moved to the cached queue
  although its usage_count hadn't dropped to 0 yet, thus freeing it before
  pages that deserved it more.
* move_page_to_active_or_inactive_queue():
  - Was ignoring the page's modified flag, thus potentially moving a modified
    page to the cached queue. That could happen only in rare cases though,
    like when the page was still mmap()ped while being written and modified and
    unmapped before being done.
  - No longer move the page to the inactive queue, even if its usage count is 0.
    In idle mode the page daemon doesn't look at inactive pages, so the page's
    stats wouldn't be updated anymore.
  - Renamed to move_page_to_appropriate_queue().


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@35499 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2010-02-16 17:12:42 +00:00
parent 665e7ac629
commit 6949076049

View File

@ -1082,6 +1082,7 @@ set_page_state(vm_page *page, int pageState)
break;
case PAGE_STATE_CACHED:
ASSERT(page->wired_count == 0 && page->mappings.IsEmpty());
ASSERT(!page->modified);
toQueue = &sCachedPageQueue;
break;
case PAGE_STATE_FREE:
@ -1128,23 +1129,22 @@ set_page_state(vm_page *page, int pageState)
}
/*! Moves a modified page into either the active or inactive page queue
depending on its usage count and wiring.
/*! Moves a previously modified page into a now appropriate queue.
The page queues must not be locked.
*/
static void
move_page_to_active_or_inactive_queue(vm_page *page)
move_page_to_appropriate_queue(vm_page *page)
{
DEBUG_PAGE_ACCESS_CHECK(page);
// Note, this logic must be in sync with what the page daemon does
// Note, this logic must be in sync with what the page daemon does.
int32 state;
if (page->mappings.IsEmpty() && page->wired_count == 0)
state = PAGE_STATE_CACHED;
else if (page->usage_count > 0)
if (!page->mappings.IsEmpty() || page->wired_count > 0)
state = PAGE_STATE_ACTIVE;
else if (page->modified)
state = PAGE_STATE_MODIFIED;
else
state = PAGE_STATE_INACTIVE;
state = PAGE_STATE_CACHED;
// TODO: If free + cached pages are low, we might directly want to free the
// page.
@ -1431,7 +1431,7 @@ PageWriteWrapper::Done(status_t result)
if (result == B_OK) {
// put it into the active/inactive queue
move_page_to_active_or_inactive_queue(fPage);
move_page_to_appropriate_queue(fPage);
fPage->busy_writing = false;
DEBUG_PAGE_ACCESS_END(fPage);
} else {
@ -1923,6 +1923,10 @@ find_cached_page_candidate(struct vm_page &marker)
static bool
free_cached_page(vm_page *page, bool dontWait)
{
ASSERT(!page->busy);
ASSERT(!page->modified);
ASSERT(page->wired_count == 0 && page->mappings.IsEmpty());
// try to lock the page's cache
if (vm_cache_acquire_locked_page_cache(page, dontWait) == NULL)
return false;
@ -2151,7 +2155,7 @@ full_scan_inactive_pages(page_stats& pageStats, int32 despairLevel)
pagesToActive++;
} else
vm_page_requeue(page, true);
} if (isMapped) {
} else if (isMapped) {
vm_page_requeue(page, true);
} else if (!page->modified) {
set_page_state(page, PAGE_STATE_CACHED);