* The callback object created in WriteAsync() was never deleted. Thus

eventually the VIP heap would be exhausted.
* WriteAsync() didn't call the provided callback when an error occurred
  before invoking vfs_asynchronous_write_pages(). The page writer would
  get stuck in those cases.
* The object cache used for the swap blocks does now use the
  asynchronous resizing feature to avoid deadlocks.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27101 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2008-08-21 03:28:35 +00:00
parent 1cda5944ad
commit 4f2d40ec1b

View File

@ -45,6 +45,10 @@
# define TRACE(x) ;
#endif
// number of free swap blocks the object cache shall minimally have
#define MIN_SWAP_BLOCK_RESERVE 4096
#define SWAP_BLOCK_PAGES 32
#define SWAP_BLOCK_SHIFT 5 /* 1 << SWAP_BLOCK_SHIFT == SWAP_BLOCK_PAGES */
#define SWAP_BLOCK_MASK (SWAP_BLOCK_PAGES - 1)
@ -349,6 +353,13 @@ public:
}
fNextCallback->IOFinished(status, partialTransfer, bytesTransferred);
delete this;
}
void operator delete(void* address, size_t size)
{
io_request_free(address);
}
private:
@ -531,8 +542,10 @@ VMAnonymousCache::WriteAsync(off_t offset, const iovec* vecs, size_t count,
// If the page doesn't have any swap space yet, allocate it.
if (newSlot) {
AutoLocker<VMCache> locker(this);
if (fAllocatedSwapSize + B_PAGE_SIZE > fCommittedSwapSize)
if (fAllocatedSwapSize + B_PAGE_SIZE > fCommittedSwapSize) {
_callback->IOFinished(B_ERROR, true, 0);
return B_ERROR;
}
fAllocatedSwapSize += B_PAGE_SIZE;
@ -551,6 +564,7 @@ VMAnonymousCache::WriteAsync(off_t offset, const iovec* vecs, size_t count,
swap_slot_dealloc(slotIndex, 1);
}
_callback->IOFinished(B_NO_MEMORY, true, 0);
return B_NO_MEMORY;
}
// TODO: If the page already had swap space assigned, we don't need an own
@ -917,9 +931,18 @@ swap_init(void)
if (sSwapBlockCache == NULL)
panic("swap_init(): can't create object cache for swap blocks\n");
status_t error = object_cache_set_minimum_reserve(sSwapBlockCache,
MIN_SWAP_BLOCK_RESERVE);
if (error != B_OK) {
panic("swap_init(): object_cache_set_minimum_reserve() failed: %s",
strerror(error));
}
// init swap hash table
sSwapHashTable.Init();
mutex_init(&sSwapHashLock, "swaphash");
// TODO: The hash table needs a special resizing strategy. Otherwise we could
// deadlock while trying swap pages out.
// init swap file list
mutex_init(&sSwapFileListLock, "swaplist");