diff --git a/headers/private/package/hpkg/PackageFileHeapAccessorBase.h b/headers/private/package/hpkg/PackageFileHeapAccessorBase.h index 904778c8f2..d53f0bd45b 100644 --- a/headers/private/package/hpkg/PackageFileHeapAccessorBase.h +++ b/headers/private/package/hpkg/PackageFileHeapAccessorBase.h @@ -100,6 +100,7 @@ public: static const size_t kChunkSize = 64 * 1024; #if defined(_KERNEL_MODE) static void* sQuadChunkCache; + static void* sQuadChunkFallbackBuffer; #endif protected: diff --git a/src/add-ons/kernel/file_systems/packagefs/kernel_interface.cpp b/src/add-ons/kernel/file_systems/packagefs/kernel_interface.cpp index e66058267c..7b56630c23 100644 --- a/src/add-ons/kernel/file_systems/packagefs/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/kernel_interface.cpp @@ -1153,7 +1153,8 @@ packagefs_std_ops(int32 op, ...) create_object_cache("pkgfs heap buffers", PackageFileHeapAccessorBase::kChunkSize * 4, 0); - object_cache_set_minimum_reserve(quadChunkCache, 1); + PackageFileHeapAccessorBase::sQuadChunkFallbackBuffer = + object_cache_alloc(quadChunkCache, 0); TwoKeyAVLTreeNode::sNodeCache = create_object_cache("pkgfs TKAVLTreeNodes", @@ -1176,6 +1177,9 @@ packagefs_std_ops(int32 op, ...) PRINT("package_std_ops(): B_MODULE_UNINIT\n"); PackageFSRoot::GlobalUninit(); delete_object_cache(TwoKeyAVLTreeNode::sNodeCache); + object_cache_free((object_cache*) + PackageFileHeapAccessorBase::sQuadChunkCache, + PackageFileHeapAccessorBase::sQuadChunkFallbackBuffer, 0); delete_object_cache((object_cache*) PackageFileHeapAccessorBase::sQuadChunkCache); StringConstants::Cleanup(); diff --git a/src/kits/package/hpkg/PackageFileHeapAccessorBase.cpp b/src/kits/package/hpkg/PackageFileHeapAccessorBase.cpp index e0c6d3f6bd..bfb98be661 100644 --- a/src/kits/package/hpkg/PackageFileHeapAccessorBase.cpp +++ b/src/kits/package/hpkg/PackageFileHeapAccessorBase.cpp @@ -11,7 +11,8 @@ #include #include -#ifdef _KERNEL_MODE +#if defined(_KERNEL_MODE) && !defined(_BOOT_MODE) +#include #include #endif @@ -30,8 +31,10 @@ namespace BHPKG { namespace BPrivate { -#if defined(_KERNEL_MODE) +#if defined(_KERNEL_MODE) && !defined(_BOOT_MODE) void* PackageFileHeapAccessorBase::sQuadChunkCache = NULL; +void* PackageFileHeapAccessorBase::sQuadChunkFallbackBuffer = NULL; +static mutex sFallbackBufferLock = MUTEX_INITIALIZER("PackageFileHeapAccessorBase fallback buffer"); #endif @@ -239,9 +242,16 @@ PackageFileHeapAccessorBase::ReadDataToOutput(off_t offset, size_t size, }; 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; + MutexLocker fallbackBufferLocker(sFallbackBufferLock, false, false); + if (quadChunkBuffer == NULL) { + fallbackBufferLocker.Lock(); + quadChunkBuffer = (uint8*)sQuadChunkFallbackBuffer; + } + // segment data buffer iovec localScratch; compressedDataBuffer = (uint16*)(quadChunkBuffer + 0);