Patch by Zhao Shuai with small changes by myself:
* Some renaming: A location in a swap file where a page can be stored is now called "slot" instead of "page" or "swap page". * swap_slot_alloc(): Update the hint more correctly after allocating slots at the hint. * swap_space_reserve(): When less than the requested space could be reserved, it always returned 0 and leaked the remaining pages. * swap_file_delete(): sSwapFileListLock wasn't unlocked in error cases. Use MutexLocker now. * swap_free_page_swap_space(): sAvailSwapSpace wasn't updated. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27057 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
2a79a7686f
commit
7fd3b44794
@ -25,6 +25,7 @@
|
||||
#include <heap.h>
|
||||
#include <slab/Slab.h>
|
||||
#include <syscalls.h>
|
||||
#include <util/AutoLock.h>
|
||||
#include <util/DoublyLinkedList.h>
|
||||
#include <util/OpenHashTable.h>
|
||||
#include <vfs.h>
|
||||
@ -46,7 +47,7 @@
|
||||
#define SWAP_BLOCK_SHIFT 5 /* 1 << SWAP_BLOCK_SHIFT == SWAP_BLOCK_PAGES */
|
||||
#define SWAP_BLOCK_MASK (SWAP_BLOCK_PAGES - 1)
|
||||
|
||||
#define SWAP_PAGE_NONE (~(swap_addr_t)0)
|
||||
#define SWAP_SLOT_NONE (~(swap_addr_t)0)
|
||||
|
||||
// bitmap allocation macros
|
||||
#define NUM_BYTES_PER_WORD 4
|
||||
@ -67,11 +68,11 @@
|
||||
|
||||
struct swap_file : DoublyLinkedListLinkImpl<swap_file> {
|
||||
struct vnode *vnode;
|
||||
swap_addr_t first_page;
|
||||
swap_addr_t last_page;
|
||||
swap_addr_t used; // # of pages used
|
||||
uint32 *maps; // bitmap for the pages
|
||||
swap_addr_t hint; // next free page
|
||||
swap_addr_t first_slot;
|
||||
swap_addr_t last_slot;
|
||||
swap_addr_t used; // # of slots used
|
||||
uint32 *maps; // bitmap for the slots
|
||||
swap_addr_t hint; // next free slot
|
||||
};
|
||||
|
||||
struct swap_hash_key {
|
||||
@ -83,7 +84,7 @@ struct swap_hash_key {
|
||||
struct swap_block : HashTableLink<swap_block> {
|
||||
swap_hash_key key;
|
||||
uint32 used;
|
||||
swap_addr_t swap_pages[SWAP_BLOCK_PAGES];
|
||||
swap_addr_t swap_slots[SWAP_BLOCK_PAGES];
|
||||
};
|
||||
|
||||
struct SwapHashTableDefinition {
|
||||
@ -135,26 +136,26 @@ static object_cache *sSwapBlockCache;
|
||||
|
||||
|
||||
static swap_addr_t
|
||||
swap_page_alloc(uint32 npages)
|
||||
swap_slot_alloc(uint32 count)
|
||||
{
|
||||
mutex_lock(&sSwapFileListLock);
|
||||
|
||||
if (sSwapFileList.IsEmpty()) {
|
||||
mutex_unlock(&sSwapFileListLock);
|
||||
panic("swap_page_alloc(): no swap file in the system\n");
|
||||
return SWAP_PAGE_NONE;
|
||||
panic("swap_slot_alloc(): no swap file in the system\n");
|
||||
return SWAP_SLOT_NONE;
|
||||
}
|
||||
|
||||
// compute how many pages are free in all swap files
|
||||
uint32 freeSwapPages = 0;
|
||||
for (SwapFileList::Iterator it = sSwapFileList.GetIterator();
|
||||
swap_file *file = it.Next();)
|
||||
freeSwapPages += file->last_page - file->first_page - file->used;
|
||||
freeSwapPages += file->last_slot - file->first_slot - file->used;
|
||||
|
||||
if (freeSwapPages < npages) {
|
||||
if (freeSwapPages < count) {
|
||||
mutex_unlock(&sSwapFileListLock);
|
||||
panic("swap_page_alloc(): swap space exhausted!\n");
|
||||
return SWAP_PAGE_NONE;
|
||||
panic("swap_slot_alloc(): swap space exhausted!\n");
|
||||
return SWAP_SLOT_NONE;
|
||||
}
|
||||
|
||||
swap_addr_t hint = 0;
|
||||
@ -164,11 +165,11 @@ swap_page_alloc(uint32 npages)
|
||||
sSwapFileAlloc = sSwapFileList.First();
|
||||
|
||||
hint = sSwapFileAlloc->hint;
|
||||
swap_addr_t pageCount = sSwapFileAlloc->last_page
|
||||
- sSwapFileAlloc->first_page;
|
||||
swap_addr_t pageCount = sSwapFileAlloc->last_slot
|
||||
- sSwapFileAlloc->first_slot;
|
||||
|
||||
swap_addr_t i = 0;
|
||||
while (i < npages && (hint + npages) <= pageCount) {
|
||||
while (i < count && (hint + count) <= pageCount) {
|
||||
if (TESTBIT(sSwapFileAlloc->maps, hint + i)) {
|
||||
hint++;
|
||||
i = 0;
|
||||
@ -176,74 +177,81 @@ swap_page_alloc(uint32 npages)
|
||||
i++;
|
||||
}
|
||||
|
||||
if (i == npages)
|
||||
if (i == count)
|
||||
break;
|
||||
|
||||
// this swap_file is full, find another
|
||||
sSwapFileAlloc = sSwapFileList.GetNext(sSwapFileAlloc);
|
||||
}
|
||||
|
||||
// no swap file can alloc so many pages, we return SWAP_PAGE_NONE
|
||||
// no swap file can alloc so many pages, we return SWAP_SLOT_NONE
|
||||
// and VMAnonymousCache::Write() will adjust allocation amount
|
||||
if (j == sSwapFileCount) {
|
||||
mutex_unlock(&sSwapFileListLock);
|
||||
return SWAP_PAGE_NONE;
|
||||
return SWAP_SLOT_NONE;
|
||||
}
|
||||
|
||||
swap_addr_t swapAddress = sSwapFileAlloc->first_page + hint;
|
||||
swap_addr_t slotIndex = sSwapFileAlloc->first_slot + hint;
|
||||
|
||||
for (uint32 i = 0; i < npages; i++)
|
||||
for (uint32 i = 0; i < count; i++)
|
||||
SETBIT(sSwapFileAlloc->maps, hint + i);
|
||||
if (hint == sSwapFileAlloc->hint)
|
||||
sSwapFileAlloc->hint += npages;
|
||||
if (hint == sSwapFileAlloc->hint) {
|
||||
sSwapFileAlloc->hint += count;
|
||||
swap_addr_t pageCount = sSwapFileAlloc->last_slot
|
||||
- sSwapFileAlloc->first_slot;
|
||||
while (TESTBIT(sSwapFileAlloc->maps, sSwapFileAlloc->hint)
|
||||
&& sSwapFileAlloc->hint < pageCount) {
|
||||
sSwapFileAlloc->hint++;
|
||||
}
|
||||
}
|
||||
|
||||
sSwapFileAlloc->used += npages;
|
||||
sSwapFileAlloc->used += count;
|
||||
|
||||
// if this swap file has used more than 90% percent of its pages
|
||||
// if this swap file has used more than 90% percent of its slots
|
||||
// switch to another
|
||||
if (sSwapFileAlloc->used
|
||||
> 9 * (sSwapFileAlloc->last_page - sSwapFileAlloc->first_page) / 10)
|
||||
> 9 * (sSwapFileAlloc->last_slot - sSwapFileAlloc->first_slot) / 10)
|
||||
sSwapFileAlloc = sSwapFileList.GetNext(sSwapFileAlloc);
|
||||
|
||||
mutex_unlock(&sSwapFileListLock);
|
||||
|
||||
return swapAddress;
|
||||
return slotIndex;
|
||||
}
|
||||
|
||||
|
||||
static swap_file *
|
||||
find_swap_file(swap_addr_t swapAddress)
|
||||
find_swap_file(swap_addr_t slotIndex)
|
||||
{
|
||||
for (SwapFileList::Iterator it = sSwapFileList.GetIterator();
|
||||
swap_file *swapFile = it.Next();) {
|
||||
if (swapAddress >= swapFile->first_page
|
||||
&& swapAddress < swapFile->last_page)
|
||||
if (slotIndex >= swapFile->first_slot
|
||||
&& slotIndex < swapFile->last_slot)
|
||||
return swapFile;
|
||||
}
|
||||
|
||||
panic("find_swap_file(): can't find swap file for %ld\n", swapAddress);
|
||||
panic("find_swap_file(): can't find swap file for slot %ld\n", slotIndex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
swap_page_dealloc(swap_addr_t swapAddress, uint32 npages)
|
||||
swap_slot_dealloc(swap_addr_t slotIndex, uint32 count)
|
||||
{
|
||||
if (swapAddress == SWAP_PAGE_NONE)
|
||||
if (slotIndex == SWAP_SLOT_NONE)
|
||||
return;
|
||||
|
||||
mutex_lock(&sSwapFileListLock);
|
||||
swap_file *swapFile = find_swap_file(swapAddress);
|
||||
swap_file *swapFile = find_swap_file(slotIndex);
|
||||
|
||||
swapAddress -= swapFile->first_page;
|
||||
slotIndex -= swapFile->first_slot;
|
||||
|
||||
for (uint32 i = 0; i < npages; i++)
|
||||
CLEARBIT(swapFile->maps, swapAddress + i);
|
||||
for (uint32 i = 0; i < count; i++)
|
||||
CLEARBIT(swapFile->maps, slotIndex + i);
|
||||
|
||||
if (swapFile->hint > swapAddress)
|
||||
swapFile->hint = swapAddress;
|
||||
if (swapFile->hint > slotIndex)
|
||||
swapFile->hint = slotIndex;
|
||||
|
||||
swapFile->used -= npages;
|
||||
swapFile->used -= count;
|
||||
mutex_unlock(&sSwapFileListLock);
|
||||
}
|
||||
|
||||
@ -255,8 +263,8 @@ swap_space_reserve(off_t amount)
|
||||
if (sAvailSwapSpace >= amount)
|
||||
sAvailSwapSpace -= amount;
|
||||
else {
|
||||
sAvailSwapSpace = 0;
|
||||
amount = sAvailSwapSpace;
|
||||
sAvailSwapSpace = 0;
|
||||
}
|
||||
mutex_unlock(&sAvailSwapSpaceLock);
|
||||
|
||||
@ -281,11 +289,11 @@ VMAnonymousCache::~VMAnonymousCache()
|
||||
// free allocated swap space and swap block
|
||||
for (off_t offset = virtual_base, toFree = fAllocatedSwapSize;
|
||||
offset < virtual_end && toFree > 0; offset += B_PAGE_SIZE) {
|
||||
swap_addr_t swapAddr = _SwapBlockGetAddress(offset >> PAGE_SHIFT);
|
||||
if (swapAddr == SWAP_PAGE_NONE)
|
||||
swap_addr_t slotIndex = _SwapBlockGetAddress(offset >> PAGE_SHIFT);
|
||||
if (slotIndex == SWAP_SLOT_NONE)
|
||||
continue;
|
||||
|
||||
swap_page_dealloc(swapAddr, 1);
|
||||
swap_slot_dealloc(slotIndex, 1);
|
||||
_SwapBlockFree(offset >> PAGE_SHIFT, 1);
|
||||
toFree -= B_PAGE_SIZE;
|
||||
}
|
||||
@ -339,7 +347,7 @@ VMAnonymousCache::Commit(off_t size)
|
||||
bool
|
||||
VMAnonymousCache::HasPage(off_t offset)
|
||||
{
|
||||
if (_SwapBlockGetAddress(offset >> PAGE_SHIFT) != SWAP_PAGE_NONE)
|
||||
if (_SwapBlockGetAddress(offset >> PAGE_SHIFT) != SWAP_SLOT_NONE)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@ -353,16 +361,16 @@ VMAnonymousCache::Read(off_t offset, const iovec *vecs, size_t count,
|
||||
off_t pageIndex = offset >> PAGE_SHIFT;
|
||||
|
||||
for (uint32 i = 0, j = 0; i < count; i = j) {
|
||||
swap_addr_t startSwapAddr = _SwapBlockGetAddress(pageIndex + i);
|
||||
swap_addr_t startSlotIndex = _SwapBlockGetAddress(pageIndex + i);
|
||||
for (j = i + 1; j < count; j++) {
|
||||
swap_addr_t swapAddr = _SwapBlockGetAddress(pageIndex + j);
|
||||
if (swapAddr != startSwapAddr + j - i)
|
||||
swap_addr_t slotIndex = _SwapBlockGetAddress(pageIndex + j);
|
||||
if (slotIndex != startSlotIndex + j - i)
|
||||
break;
|
||||
}
|
||||
|
||||
swap_file *swapFile = find_swap_file(startSwapAddr);
|
||||
swap_file *swapFile = find_swap_file(startSlotIndex);
|
||||
|
||||
off_t pos = (startSwapAddr - swapFile->first_page) * PAGE_SIZE;
|
||||
off_t pos = (startSlotIndex - swapFile->first_slot) * B_PAGE_SIZE;
|
||||
|
||||
status_t status = vfs_read_pages(swapFile->vnode, NULL, pos, vecs + i,
|
||||
j - i, 0, _numBytes);
|
||||
@ -382,9 +390,9 @@ VMAnonymousCache::Write(off_t offset, const iovec *vecs, size_t count,
|
||||
|
||||
Lock();
|
||||
for (uint32 i = 0; i < count; i++) {
|
||||
swap_addr_t swapAddr = _SwapBlockGetAddress(pageIndex + i);
|
||||
if (swapAddr != SWAP_PAGE_NONE) {
|
||||
swap_page_dealloc(swapAddr, 1);
|
||||
swap_addr_t slotIndex = _SwapBlockGetAddress(pageIndex + i);
|
||||
if (slotIndex != SWAP_SLOT_NONE) {
|
||||
swap_slot_dealloc(slotIndex, 1);
|
||||
_SwapBlockFree(pageIndex + i, 1);
|
||||
fAllocatedSwapSize -= B_PAGE_SIZE;
|
||||
}
|
||||
@ -398,16 +406,16 @@ VMAnonymousCache::Write(off_t offset, const iovec *vecs, size_t count,
|
||||
|
||||
uint32 n = count;
|
||||
for (uint32 i = 0; i < count; i += n) {
|
||||
swap_addr_t swapAddr;
|
||||
// try to allocate n pages, if fail, try to allocate n/2
|
||||
while ((swapAddr = swap_page_alloc(n)) == SWAP_PAGE_NONE && n >= 2)
|
||||
swap_addr_t slotIndex;
|
||||
// try to allocate n slots, if fail, try to allocate n/2
|
||||
while ((slotIndex = swap_slot_alloc(n)) == SWAP_SLOT_NONE && n >= 2)
|
||||
n >>= 1;
|
||||
if (swapAddr == SWAP_PAGE_NONE)
|
||||
if (slotIndex == SWAP_SLOT_NONE)
|
||||
panic("VMAnonymousCache::Write(): can't allocate swap space\n");
|
||||
|
||||
swap_file *swapFile = find_swap_file(swapAddr);
|
||||
swap_file *swapFile = find_swap_file(slotIndex);
|
||||
|
||||
off_t pos = (swapAddr - swapFile->first_page) * B_PAGE_SIZE;
|
||||
off_t pos = (slotIndex - swapFile->first_slot) * B_PAGE_SIZE;
|
||||
|
||||
status_t status = vfs_write_pages(swapFile->vnode, NULL, pos, vecs + i,
|
||||
n, flags, _numBytes);
|
||||
@ -416,11 +424,11 @@ VMAnonymousCache::Write(off_t offset, const iovec *vecs, size_t count,
|
||||
fAllocatedSwapSize -= n * B_PAGE_SIZE;
|
||||
Unlock();
|
||||
|
||||
swap_page_dealloc(swapAddr, n);
|
||||
swap_slot_dealloc(slotIndex, n);
|
||||
return status;
|
||||
}
|
||||
|
||||
_SwapBlockBuild(pageIndex + i, swapAddr, n);
|
||||
_SwapBlockBuild(pageIndex + i, slotIndex, n);
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
@ -451,8 +459,8 @@ VMAnonymousCache::Fault(struct vm_address_space *aspace, off_t offset)
|
||||
|
||||
if (fPrecommittedPages == 0) {
|
||||
// try to commit additional swap space/memory
|
||||
if (swap_space_reserve(PAGE_SIZE) == PAGE_SIZE)
|
||||
fCommittedSwapSize += PAGE_SIZE;
|
||||
if (swap_space_reserve(B_PAGE_SIZE) == B_PAGE_SIZE)
|
||||
fCommittedSwapSize += B_PAGE_SIZE;
|
||||
else if (vm_try_reserve_memory(B_PAGE_SIZE, 0) != B_OK)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
@ -487,29 +495,29 @@ VMAnonymousCache::MergeStore(VMCache* _source)
|
||||
_Commit(actualSize);
|
||||
|
||||
for (off_t offset = source->virtual_base; offset < source->virtual_end;
|
||||
offset += PAGE_SIZE) {
|
||||
offset += B_PAGE_SIZE) {
|
||||
off_t pageIndex = offset >> PAGE_SHIFT;
|
||||
swap_addr_t sourceSwapIndex = source->_SwapBlockGetAddress(pageIndex);
|
||||
swap_addr_t sourceSlotIndex = source->_SwapBlockGetAddress(pageIndex);
|
||||
|
||||
if (sourceSwapIndex == SWAP_PAGE_NONE)
|
||||
if (sourceSlotIndex == SWAP_SLOT_NONE)
|
||||
// this page is not swapped out
|
||||
continue;
|
||||
|
||||
if (LookupPage(offset)) {
|
||||
// this page is shadowed and we can find it in the new cache,
|
||||
// free the swap space
|
||||
swap_page_dealloc(sourceSwapIndex, 1);
|
||||
swap_slot_dealloc(sourceSlotIndex, 1);
|
||||
} else {
|
||||
swap_addr_t swapIndex = _SwapBlockGetAddress(pageIndex);
|
||||
swap_addr_t slotIndex = _SwapBlockGetAddress(pageIndex);
|
||||
|
||||
if (swapIndex == SWAP_PAGE_NONE) {
|
||||
if (slotIndex == SWAP_SLOT_NONE) {
|
||||
// the page is not shadowed,
|
||||
// assign the swap address to the new cache
|
||||
_SwapBlockBuild(pageIndex, sourceSwapIndex, 1);
|
||||
_SwapBlockBuild(pageIndex, sourceSlotIndex, 1);
|
||||
fAllocatedSwapSize += B_PAGE_SIZE;
|
||||
} else {
|
||||
// the page is shadowed and is also swapped out
|
||||
swap_page_dealloc(sourceSwapIndex, 1);
|
||||
swap_slot_dealloc(sourceSlotIndex, 1);
|
||||
}
|
||||
}
|
||||
source->fAllocatedSwapSize -= B_PAGE_SIZE;
|
||||
@ -520,13 +528,13 @@ VMAnonymousCache::MergeStore(VMCache* _source)
|
||||
|
||||
void
|
||||
VMAnonymousCache::_SwapBlockBuild(off_t startPageIndex,
|
||||
swap_addr_t startSwapAddress, uint32 count)
|
||||
swap_addr_t startSlotIndex, uint32 count)
|
||||
{
|
||||
mutex_lock(&sSwapHashLock);
|
||||
|
||||
for (uint32 i = 0; i < count; i++) {
|
||||
off_t pageIndex = startPageIndex + i;
|
||||
swap_addr_t swapAddress = startSwapAddress + i;
|
||||
swap_addr_t slotIndex = startSlotIndex + i;
|
||||
|
||||
swap_hash_key key = { this, pageIndex };
|
||||
|
||||
@ -544,13 +552,13 @@ VMAnonymousCache::_SwapBlockBuild(off_t startPageIndex,
|
||||
swap->key.page_index = pageIndex & ~(off_t)SWAP_BLOCK_MASK;
|
||||
swap->used = 0;
|
||||
for (uint32 i = 0; i < SWAP_BLOCK_PAGES; i++)
|
||||
swap->swap_pages[i] = SWAP_PAGE_NONE;
|
||||
swap->swap_slots[i] = SWAP_SLOT_NONE;
|
||||
|
||||
sSwapHashTable.Insert(swap);
|
||||
}
|
||||
|
||||
swap_addr_t blockIndex = pageIndex & SWAP_BLOCK_MASK;
|
||||
swap->swap_pages[blockIndex] = swapAddress;
|
||||
swap->swap_slots[blockIndex] = slotIndex;
|
||||
|
||||
swap->used++;
|
||||
}
|
||||
@ -569,9 +577,9 @@ VMAnonymousCache::_SwapBlockFree(off_t startPageIndex, uint32 count)
|
||||
swap_hash_key key = { this, pageIndex };
|
||||
swap_block *swap = sSwapHashTable.Lookup(key);
|
||||
if (swap != NULL) {
|
||||
swap_addr_t swapAddr = swap->swap_pages[pageIndex & SWAP_BLOCK_MASK];
|
||||
if (swapAddr != SWAP_PAGE_NONE) {
|
||||
swap->swap_pages[pageIndex & SWAP_BLOCK_MASK] = SWAP_PAGE_NONE;
|
||||
swap_addr_t swapAddr = swap->swap_slots[pageIndex & SWAP_BLOCK_MASK];
|
||||
if (swapAddr != SWAP_SLOT_NONE) {
|
||||
swap->swap_slots[pageIndex & SWAP_BLOCK_MASK] = SWAP_SLOT_NONE;
|
||||
swap->used--;
|
||||
if (swap->used == 0) {
|
||||
sSwapHashTable.Remove(swap);
|
||||
@ -592,16 +600,16 @@ VMAnonymousCache::_SwapBlockGetAddress(off_t pageIndex)
|
||||
|
||||
swap_hash_key key = { this, pageIndex };
|
||||
swap_block *swap = sSwapHashTable.Lookup(key);
|
||||
swap_addr_t swapAddress = SWAP_PAGE_NONE;
|
||||
swap_addr_t slotIndex = SWAP_SLOT_NONE;
|
||||
|
||||
if (swap != NULL) {
|
||||
swap_addr_t blockIndex = pageIndex & SWAP_BLOCK_MASK;
|
||||
swapAddress = swap->swap_pages[blockIndex];
|
||||
slotIndex = swap->swap_slots[blockIndex];
|
||||
}
|
||||
|
||||
mutex_unlock(&sSwapHashLock);
|
||||
|
||||
return swapAddress;
|
||||
return slotIndex;
|
||||
}
|
||||
|
||||
|
||||
@ -702,23 +710,22 @@ swap_file_add(char *path)
|
||||
memset(swap->maps, 0, (pageCount + 7) / 8);
|
||||
swap->hint = 0;
|
||||
|
||||
// set start page index and add this file to swap file list
|
||||
// set slot index and add this file to swap file list
|
||||
mutex_lock(&sSwapFileListLock);
|
||||
if (sSwapFileList.IsEmpty()) {
|
||||
swap->first_page = 0;
|
||||
swap->last_page = pageCount;
|
||||
}
|
||||
else {
|
||||
swap->first_slot = 0;
|
||||
swap->last_slot = pageCount;
|
||||
} else {
|
||||
// leave one page gap between two swap files
|
||||
swap->first_page = sSwapFileList.Last()->last_page + 1;
|
||||
swap->last_page = swap->first_page + pageCount;
|
||||
swap->first_slot = sSwapFileList.Last()->last_slot + 1;
|
||||
swap->last_slot = swap->first_slot + pageCount;
|
||||
}
|
||||
sSwapFileList.Add(swap);
|
||||
sSwapFileCount++;
|
||||
mutex_unlock(&sSwapFileListLock);
|
||||
|
||||
mutex_lock(&sAvailSwapSpaceLock);
|
||||
sAvailSwapSpace += pageCount * PAGE_SIZE;
|
||||
sAvailSwapSpace += pageCount * B_PAGE_SIZE;
|
||||
mutex_unlock(&sAvailSwapSpaceLock);
|
||||
|
||||
return B_OK;
|
||||
@ -730,12 +737,10 @@ swap_file_delete(char *path)
|
||||
{
|
||||
vnode *node = NULL;
|
||||
status_t status = vfs_get_vnode_from_path(path, true, &node);
|
||||
if (status != B_OK) {
|
||||
vfs_put_vnode(node);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
}
|
||||
|
||||
mutex_lock(&sSwapFileListLock);
|
||||
MutexLocker locker(sSwapFileListLock);
|
||||
|
||||
swap_file *swapFile = NULL;
|
||||
for (SwapFileList::Iterator it = sSwapFileList.GetIterator();
|
||||
@ -757,10 +762,10 @@ swap_file_delete(char *path)
|
||||
|
||||
sSwapFileList.Remove(swapFile);
|
||||
sSwapFileCount--;
|
||||
mutex_unlock(&sSwapFileListLock);
|
||||
locker.Unlock();
|
||||
|
||||
mutex_lock(&sAvailSwapSpaceLock);
|
||||
sAvailSwapSpace -= (swapFile->last_page - swapFile->first_page) * PAGE_SIZE;
|
||||
sAvailSwapSpace -= (swapFile->last_slot - swapFile->first_slot) * PAGE_SIZE;
|
||||
mutex_unlock(&sAvailSwapSpaceLock);
|
||||
|
||||
vfs_put_vnode(swapFile->vnode);
|
||||
@ -847,14 +852,19 @@ swap_free_page_swap_space(vm_page *page)
|
||||
if (cache == NULL)
|
||||
return false;
|
||||
|
||||
swap_addr_t swapAddress = cache->_SwapBlockGetAddress(page->cache_offset);
|
||||
if (swapAddress == SWAP_PAGE_NONE)
|
||||
swap_addr_t slotIndex = cache->_SwapBlockGetAddress(page->cache_offset);
|
||||
if (slotIndex == SWAP_SLOT_NONE)
|
||||
return false;
|
||||
|
||||
swap_page_dealloc(swapAddress, 1);
|
||||
swap_slot_dealloc(slotIndex, 1);
|
||||
cache->fAllocatedSwapSize -= B_PAGE_SIZE;
|
||||
cache->_SwapBlockFree(page->cache_offset, 1);
|
||||
return true;
|
||||
|
||||
mutex_lock(&sAvailSwapSpaceLock);
|
||||
sAvailSwapSpace += B_PAGE_SIZE;
|
||||
mutex_unlock(&sAvailSwapSpaceLock);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -874,14 +884,14 @@ swap_total_swap_pages()
|
||||
{
|
||||
mutex_lock(&sSwapFileListLock);
|
||||
|
||||
uint32 totalSwapPages = 0;
|
||||
uint32 totalSwapSlots = 0;
|
||||
for (SwapFileList::Iterator it = sSwapFileList.GetIterator();
|
||||
swap_file *swapFile = it.Next();)
|
||||
totalSwapPages += swapFile->last_page - swapFile->first_page;
|
||||
totalSwapSlots += swapFile->last_slot - swapFile->first_slot;
|
||||
|
||||
mutex_unlock(&sSwapFileListLock);
|
||||
|
||||
return totalSwapPages;
|
||||
return totalSwapSlots;
|
||||
}
|
||||
|
||||
#endif // ENABLE_SWAP_SUPPORT
|
||||
|
@ -47,7 +47,7 @@ public:
|
||||
|
||||
private:
|
||||
void _SwapBlockBuild(off_t pageIndex,
|
||||
swap_addr_t swapAddress, uint32 count);
|
||||
swap_addr_t slotIndex, uint32 count);
|
||||
void _SwapBlockFree(off_t pageIndex, uint32 count);
|
||||
swap_addr_t _SwapBlockGetAddress(off_t pageIndex);
|
||||
status_t _Commit(off_t size);
|
||||
|
Loading…
Reference in New Issue
Block a user