packagefs: Add a fallback buffer for reading heaps in low-memory conditions.
Otherwise we might fail with B_NO_MEMORY, or wait for long periods of time, which we don't want to do in such a critical routine. Should improve system responsiveness (or even prevent application crashes) under high memory pressure.
This commit is contained in:
@@ -100,6 +100,7 @@ public:
|
|||||||
static const size_t kChunkSize = 64 * 1024;
|
static const size_t kChunkSize = 64 * 1024;
|
||||||
#if defined(_KERNEL_MODE)
|
#if defined(_KERNEL_MODE)
|
||||||
static void* sQuadChunkCache;
|
static void* sQuadChunkCache;
|
||||||
|
static void* sQuadChunkFallbackBuffer;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -1153,7 +1153,8 @@ packagefs_std_ops(int32 op, ...)
|
|||||||
create_object_cache("pkgfs heap buffers",
|
create_object_cache("pkgfs heap buffers",
|
||||||
PackageFileHeapAccessorBase::kChunkSize * 4,
|
PackageFileHeapAccessorBase::kChunkSize * 4,
|
||||||
0);
|
0);
|
||||||
object_cache_set_minimum_reserve(quadChunkCache, 1);
|
PackageFileHeapAccessorBase::sQuadChunkFallbackBuffer =
|
||||||
|
object_cache_alloc(quadChunkCache, 0);
|
||||||
|
|
||||||
TwoKeyAVLTreeNode<void*>::sNodeCache =
|
TwoKeyAVLTreeNode<void*>::sNodeCache =
|
||||||
create_object_cache("pkgfs TKAVLTreeNodes",
|
create_object_cache("pkgfs TKAVLTreeNodes",
|
||||||
@@ -1176,6 +1177,9 @@ packagefs_std_ops(int32 op, ...)
|
|||||||
PRINT("package_std_ops(): B_MODULE_UNINIT\n");
|
PRINT("package_std_ops(): B_MODULE_UNINIT\n");
|
||||||
PackageFSRoot::GlobalUninit();
|
PackageFSRoot::GlobalUninit();
|
||||||
delete_object_cache(TwoKeyAVLTreeNode<void*>::sNodeCache);
|
delete_object_cache(TwoKeyAVLTreeNode<void*>::sNodeCache);
|
||||||
|
object_cache_free((object_cache*)
|
||||||
|
PackageFileHeapAccessorBase::sQuadChunkCache,
|
||||||
|
PackageFileHeapAccessorBase::sQuadChunkFallbackBuffer, 0);
|
||||||
delete_object_cache((object_cache*)
|
delete_object_cache((object_cache*)
|
||||||
PackageFileHeapAccessorBase::sQuadChunkCache);
|
PackageFileHeapAccessorBase::sQuadChunkCache);
|
||||||
StringConstants::Cleanup();
|
StringConstants::Cleanup();
|
||||||
|
|||||||
@@ -11,7 +11,8 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <new>
|
#include <new>
|
||||||
#ifdef _KERNEL_MODE
|
#if defined(_KERNEL_MODE) && !defined(_BOOT_MODE)
|
||||||
|
#include <util/AutoLock.h>
|
||||||
#include <slab/Slab.h>
|
#include <slab/Slab.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -30,8 +31,10 @@ namespace BHPKG {
|
|||||||
namespace BPrivate {
|
namespace BPrivate {
|
||||||
|
|
||||||
|
|
||||||
#if defined(_KERNEL_MODE)
|
#if defined(_KERNEL_MODE) && !defined(_BOOT_MODE)
|
||||||
void* PackageFileHeapAccessorBase::sQuadChunkCache = NULL;
|
void* PackageFileHeapAccessorBase::sQuadChunkCache = NULL;
|
||||||
|
void* PackageFileHeapAccessorBase::sQuadChunkFallbackBuffer = NULL;
|
||||||
|
static mutex sFallbackBufferLock = MUTEX_INITIALIZER("PackageFileHeapAccessorBase fallback buffer");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -239,9 +242,16 @@ PackageFileHeapAccessorBase::ReadDataToOutput(off_t offset, size_t size,
|
|||||||
};
|
};
|
||||||
|
|
||||||
ObjectCacheDeleter chunkBufferDeleter((object_cache*)sQuadChunkCache);
|
ObjectCacheDeleter chunkBufferDeleter((object_cache*)sQuadChunkCache);
|
||||||
uint8* quadChunkBuffer = (uint8*)object_cache_alloc((object_cache*)sQuadChunkCache, 0);
|
uint8* quadChunkBuffer = (uint8*)object_cache_alloc((object_cache*)sQuadChunkCache,
|
||||||
|
CACHE_DONT_WAIT_FOR_MEMORY);
|
||||||
chunkBufferDeleter.object = quadChunkBuffer;
|
chunkBufferDeleter.object = quadChunkBuffer;
|
||||||
|
|
||||||
|
MutexLocker fallbackBufferLocker(sFallbackBufferLock, false, false);
|
||||||
|
if (quadChunkBuffer == NULL) {
|
||||||
|
fallbackBufferLocker.Lock();
|
||||||
|
quadChunkBuffer = (uint8*)sQuadChunkFallbackBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
// segment data buffer
|
// segment data buffer
|
||||||
iovec localScratch;
|
iovec localScratch;
|
||||||
compressedDataBuffer = (uint16*)(quadChunkBuffer + 0);
|
compressedDataBuffer = (uint16*)(quadChunkBuffer + 0);
|
||||||
|
|||||||
Reference in New Issue
Block a user