From 95accc28f84960ea0b0f71f9d07660a88f9adaf6 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Mon, 11 Aug 2008 23:55:30 +0000 Subject: [PATCH] Patch by Zhao Shuai with small changes by myself: The page daemon does now also free swap space assigned to pages that are rather active. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26938 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/system/kernel/vm/vm_daemons.cpp | 45 ++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/src/system/kernel/vm/vm_daemons.cpp b/src/system/kernel/vm/vm_daemons.cpp index 034c785faf..8c30e9f7a0 100644 --- a/src/system/kernel/vm/vm_daemons.cpp +++ b/src/system/kernel/vm/vm_daemons.cpp @@ -14,6 +14,7 @@ #include #include #include +#include "VMAnonymousCache.h" const static uint32 kMinScanPagesCount = 512; @@ -154,7 +155,27 @@ check_page_activation(int32 index) } -static status_t +#if ENABLE_SWAP_SUPPORT +static bool +free_page_swap_space(int32 index) +{ + vm_page *page = vm_page_at_index(index); + PageCacheLocker locker(page); + if (!locker.IsLocked()) + return false; + + if (page->cache->temporary && page->wired_count == 0 + && page->cache->HasPage(page->cache_offset << PAGE_SHIFT) + && page->usage_count > 0) { + // TODO: how to judge a page is highly active? + return swap_free_page_swap_space(page); + } + return false; +} +#endif + + +static status_t page_daemon(void* /*unused*/) { bigtime_t scanWaitInterval = kMaxScanWaitInterval; @@ -162,6 +183,10 @@ page_daemon(void* /*unused*/) uint32 clearPage = 0; uint32 checkPage = sNumPages / 2; +#if ENABLE_SWAP_SUPPORT + uint32 swapPage = 0; +#endif + while (true) { acquire_sem_etc(sPageDaemonSem, 1, B_RELATIVE_TIMEOUT, scanWaitInterval); @@ -198,7 +223,25 @@ dprintf("wait interval %Ld, scan pages %lu, free %lu, target %lu\n", if (++checkPage == sNumPages) checkPage = 0; } + +#if ENABLE_SWAP_SUPPORT + uint32 availableSwapPages = swap_available_pages(); + if (swap_total_swap_pages() > 0 && availableSwapPages < sNumPages / 8) { + uint32 swapPagesToFree = sNumPages / 8 - availableSwapPages; + uint32 swapScanCount = kMaxScanPagesCount + - (kMaxScanPagesCount - kMinScanPagesCount) + * availableSwapPages / (sNumPages / 8); + + for (uint32 i = 0; i < swapScanCount && swapPagesToFree > 0; i++) { + if (free_page_swap_space(swapPage)) + swapPagesToFree--; + if (++swapPage == sNumPages) + swapPage = 0; + } + } +#endif } + return B_OK; }