From 33e590dfd7e70f9118133aac6a0fe2397160c84e Mon Sep 17 00:00:00 2001 From: wonghiu45 Date: Thu, 8 Jun 2023 16:36:15 +0800 Subject: [PATCH] add purgeable data lock to support purgeable pixelmap category:bugfix issue:https://gitee.com/openharmony/commonlibrary_memory_utils/issues/I7BZWC Signed-off-by: wonghiu45 Change-Id: Ib4b8b0512166cc34ff0b06e03866b5f143730da4 --- .../cpp/include/purgeable_mem_base.h | 6 ++++ .../cpp/include/purgeable_resource_manager.h | 6 ++-- .../cpp/src/purgeable_mem_base.cpp | 32 +++++++++++++++++++ .../cpp/src/purgeable_resource_manager.cpp | 10 ++++-- .../include/purgeable_pixelmap_builder.h | 1 + .../src/purgeable_pixelmap_builder.cpp | 23 ++++++++++++- 6 files changed, 72 insertions(+), 6 deletions(-) diff --git a/libpurgeablemem/cpp/include/purgeable_mem_base.h b/libpurgeablemem/cpp/include/purgeable_mem_base.h index 5426df6..4bf2f74 100644 --- a/libpurgeablemem/cpp/include/purgeable_mem_base.h +++ b/libpurgeablemem/cpp/include/purgeable_mem_base.h @@ -91,6 +91,10 @@ public: */ virtual void ResizeData(size_t newSize); void SetRebuildSuccessCallback(std::function &callback); + bool IsDataValid(); + void SetDataValid(bool target); + bool BeginReadWithDataLock(); + void EndReadWithDataLock(); PurgeableMemBase(); virtual ~PurgeableMemBase(); @@ -101,6 +105,8 @@ public: protected: void *dataPtr_ = nullptr; + std::mutex dataLock_; + bool isDataValid_ {true}; size_t dataSizeInput_ = 0; std::unique_ptr builder_ = nullptr; std::shared_mutex rwlock_; diff --git a/libpurgeablemem/cpp/include/purgeable_resource_manager.h b/libpurgeablemem/cpp/include/purgeable_resource_manager.h index 3fb3b9b..9407ff1 100644 --- a/libpurgeablemem/cpp/include/purgeable_resource_manager.h +++ b/libpurgeablemem/cpp/include/purgeable_resource_manager.h @@ -30,12 +30,12 @@ namespace PurgeableMem { const std::string THREAD_POOL_TASK_NUMBER_SYS_NAME = "persist.commonlibrary.purgeable.threadpooltasknum"; const std::string LRU_CACHE_CAPACITY_SYS_NAME = "persist.commonlibrary.purgeable.lrucachecapacity"; /* Threadpool task number and lrucache capacity */ -constexpr int32_t THREAD_POOL_TASK_NUMBER = 8; +constexpr int32_t THREAD_POOL_TASK_NUMBER = 4; constexpr int32_t MIN_THREAD_POOL_TASK_NUMBER = 1; constexpr int32_t MAX_THREAD_POOL_TASK_NUMBER = 20; -constexpr int32_t LRU_CACHE_CAPACITY = 100; +constexpr int32_t LRU_CACHE_CAPACITY = 500; constexpr int32_t MIN_LRU_CACHE_CAPACITY = 1; -constexpr int32_t MAX_LRU_CACHE_CAPACITY = 200; +constexpr int32_t MAX_LRU_CACHE_CAPACITY = 2000; class LruCache { public: diff --git a/libpurgeablemem/cpp/src/purgeable_mem_base.cpp b/libpurgeablemem/cpp/src/purgeable_mem_base.cpp index f4150dc..cb070c9 100644 --- a/libpurgeablemem/cpp/src/purgeable_mem_base.cpp +++ b/libpurgeablemem/cpp/src/purgeable_mem_base.cpp @@ -152,6 +152,28 @@ void PurgeableMemBase::EndWrite() Unpin(); } +bool PurgeableMemBase::BeginReadWithDataLock() +{ + std::lock_guard lock(dataLock_); + + if (isDataValid_) { + return BeginRead(); + } + + return false; +} + +void PurgeableMemBase::EndReadWithDataLock() +{ + std::lock_guard lock(dataLock_); + + if (isDataValid_) { + EndRead(); + } + + return; +} + bool PurgeableMemBase::ModifyContentByBuilder(std::unique_ptr modifier) { IF_NULL_LOG_ACTION(modifier, "input modifier is nullptr", return false); @@ -241,5 +263,15 @@ void PurgeableMemBase::SetRebuildSuccessCallback(std::function &callback builder_->SetRebuildSuccessCallback(callback); } } + +bool PurgeableMemBase::IsDataValid() +{ + return isDataValid_; +} + +void PurgeableMemBase::SetDataValid(bool target) +{ + isDataValid_ = target; +} } /* namespace PurgeableMem */ } /* namespace OHOS */ diff --git a/libpurgeablemem/cpp/src/purgeable_resource_manager.cpp b/libpurgeablemem/cpp/src/purgeable_resource_manager.cpp index 458a913..04dbbd1 100644 --- a/libpurgeablemem/cpp/src/purgeable_resource_manager.cpp +++ b/libpurgeablemem/cpp/src/purgeable_resource_manager.cpp @@ -39,6 +39,9 @@ void LruCache::Insert(std::shared_ptr key) return; } + std::lock_guard dataLock(key->dataLock_); + key->SetDataValid(true); + auto resourcePtrIter = positionMap_.find(key); if (resourcePtrIter != positionMap_.end()) { resourcePtrList_.splice(resourcePtrList_.begin(), resourcePtrList_, resourcePtrIter->second); @@ -64,6 +67,9 @@ void LruCache::Erase(std::shared_ptr key) return; } + std::lock_guard dataLock(key->dataLock_); + key->SetDataValid(false); + auto resourcePtrIter = positionMap_.find(key); if (resourcePtrIter == positionMap_.end()) { return; @@ -139,7 +145,7 @@ void PurgeableResourceManager::BeginAccessPurgeableMem() continue; } - auto task = std::bind(&PurgeableMemBase::BeginRead, resourcePtr); + auto task = std::bind(&PurgeableMemBase::BeginReadWithDataLock, resourcePtr); threadPool_.AddTask(task); } @@ -158,7 +164,7 @@ void PurgeableResourceManager::EndAccessPurgeableMem() continue; } - auto task = std::bind(&PurgeableMemBase::EndRead, resourcePtr); + auto task = std::bind(&PurgeableMemBase::EndReadWithDataLock, resourcePtr); threadPool_.AddTask(task); } diff --git a/purgeable_builder/include/purgeable_pixelmap_builder.h b/purgeable_builder/include/purgeable_pixelmap_builder.h index 83aaba2..3a357e0 100644 --- a/purgeable_builder/include/purgeable_pixelmap_builder.h +++ b/purgeable_builder/include/purgeable_pixelmap_builder.h @@ -52,6 +52,7 @@ void RemoveFromPurgeableResourceMgr(std::shared_ptr &pixelMap); void AddToPurgeableResourceMgr(std::unique_ptr &pixelMap); bool MakePixelMapToBePurgeable(std::unique_ptr &pixelMap, std::unique_ptr &backupImgSrc4Rebuild, DecodeOptions &decodeOpts); +bool IfCanBePurgeable(DecodeOptions &decodeOpts); } // namespace PurgeableBuilder } // namespace OHOS #endif /* OHOS_MEMORY_UTILS_PURGEABLE_PIXELMAP_BUILDER_H */ \ No newline at end of file diff --git a/purgeable_builder/src/purgeable_pixelmap_builder.cpp b/purgeable_builder/src/purgeable_pixelmap_builder.cpp index 503743e..0a8ca4a 100644 --- a/purgeable_builder/src/purgeable_pixelmap_builder.cpp +++ b/purgeable_builder/src/purgeable_pixelmap_builder.cpp @@ -32,6 +32,11 @@ namespace OHOS { namespace PurgeableBuilder { constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0xD001799, "PurgeablePixelMapBuilder" }; +constexpr int THRESHOLD_HEIGHT = 256; +constexpr int THRESHOLD_WIDGHT = 256; +const std::string SYSTEM_PARAM_PURGEABLE_ENABLE = "persist.memmgr.purgeable.enable"; +const std::string SYSTEM_PARAM_PIXELMAP_THRESHOLD_HEIGHT = "persist.memmgr.purgeable.pixelmap.threshold.height"; +const std::string SYSTEM_PARAM_PIXELMAP_THRESHOLD_WIDGHT = "persist.memmgr.purgeable.pixelmap.threshold.widght"; PurgeablePixelMapBuilder::PurgeablePixelMapBuilder(uint32_t index, std::unique_ptr &imageSource, DecodeOptions opts, PixelMap *pixelMap) @@ -66,7 +71,7 @@ bool PurgeablePixelMapBuilder::Build(void *data, size_t size) bool GetSysForPurgeable() { - return system::GetBoolParameter("persist.memmgr.purgeable.enable", false); + return system::GetBoolParameter(SYSTEM_PARAM_PURGEABLE_ENABLE, false); } void SetBuilderToBePurgeable(std::unique_ptr &pixelMap, @@ -120,6 +125,18 @@ void AddToPurgeableResourceMgr(std::unique_ptr &pixelMap) FinishTrace(HITRACE_TAG_ZIMAGE); } +bool IfCanBePurgeable(DecodeOptions &decodeOpts) +{ + int thresholdHeight = system::GetIntParameter(SYSTEM_PARAM_PIXELMAP_THRESHOLD_HEIGHT, THRESHOLD_HEIGHT); + int thresholdWidght = system::GetIntParameter(SYSTEM_PARAM_PIXELMAP_THRESHOLD_WIDGHT, THRESHOLD_WIDGHT); + Size size = decodeOpts.desiredSize; + + if (size.height > thresholdHeight || size.width > thresholdWidght) { + return false; + } + return true; +} + bool MakePixelMapToBePurgeable(std::unique_ptr &pixelMap, std::unique_ptr &backupImgSrc4Rebuild, DecodeOptions &decodeOpts) { @@ -130,6 +147,10 @@ bool MakePixelMapToBePurgeable(std::unique_ptr &pixelMap, std::unique_ return false; } + if (!IfCanBePurgeable(decodeOpts)) { + return false; + } + if (pixelMap == nullptr || backupImgSrc4Rebuild == nullptr) { HiviewDFX::HiLog::Error(LABEL, "PixelMap or backupImgSrc4Rebuild is null."); return false; -- Gitee