From 84c16c5e89eb9f0369a987a08b626dfbb01abf65 Mon Sep 17 00:00:00 2001 From: lushi Date: Sat, 26 Feb 2022 22:18:06 +0800 Subject: [PATCH] enable low priority bgtasks Signed-off-by: lushi Change-Id: I5488160dee73b841d0f3e3192e418467c2f59b90 --- .../base/thread/background_task_executor.cpp | 35 ++++++++++++++----- .../base/thread/background_task_executor.h | 10 ++++-- frameworks/core/image/image_loader.cpp | 32 ++++++----------- frameworks/core/image/image_loader.h | 1 - frameworks/core/image/image_provider.cpp | 15 +++++--- 5 files changed, 55 insertions(+), 38 deletions(-) diff --git a/frameworks/base/thread/background_task_executor.cpp b/frameworks/base/thread/background_task_executor.cpp index d47d026c412..75927bf733c 100644 --- a/frameworks/base/thread/background_task_executor.cpp +++ b/frameworks/base/thread/background_task_executor.cpp @@ -73,7 +73,7 @@ BackgroundTaskExecutor::~BackgroundTaskExecutor() } } -bool BackgroundTaskExecutor::PostTask(Task&& task) +bool BackgroundTaskExecutor::PostTask(Task&& task, BgTaskPriority priority) { if (!task) { return false; @@ -83,12 +83,19 @@ bool BackgroundTaskExecutor::PostTask(Task&& task) if (!running_) { return false; } - tasks_.emplace_back(std::move(task)); + switch (priority) { + case BgTaskPriority::LOW: + lowPriorityTasks_.emplace_back(std::move(task)); + break; + default: + tasks_.emplace_back(std::move(task)); + break; + } condition_.notify_one(); return true; } -bool BackgroundTaskExecutor::PostTask(const Task& task) +bool BackgroundTaskExecutor::PostTask(const Task& task, BgTaskPriority priority) { if (!task) { return false; @@ -98,7 +105,14 @@ bool BackgroundTaskExecutor::PostTask(const Task& task) if (!running_) { return false; } - tasks_.emplace_back(task); + switch (priority) { + case BgTaskPriority::LOW: + lowPriorityTasks_.emplace_back(task); + break; + default: + tasks_.emplace_back(task); + break; + } condition_.notify_one(); return true; } @@ -150,7 +164,7 @@ void BackgroundTaskExecutor::ThreadLoop(uint32_t threadNo) const uint32_t purgeFlag = (1 << (threadNo - 1)); std::unique_lock lock(mutex_); while (running_) { - if (tasks_.empty()) { + if (tasks_.empty() && lowPriorityTasks_.empty()) { if ((purgeFlags_ & purgeFlag) != purgeFlag) { condition_.wait(lock); continue; @@ -163,9 +177,14 @@ void BackgroundTaskExecutor::ThreadLoop(uint32_t threadNo) purgeFlags_ &= ~purgeFlag; continue; } - - task = std::move(tasks_.front()); - tasks_.pop_front(); + // deal with tasks_ first. do lowPriorityTasks_ only when all tasks_ done. + if (!tasks_.empty()) { + task = std::move(tasks_.front()); + tasks_.pop_front(); + } else { + task = std::move(lowPriorityTasks_.front()); + lowPriorityTasks_.pop_front(); + } lock.unlock(); // Execute the task and clear after execution. diff --git a/frameworks/base/thread/background_task_executor.h b/frameworks/base/thread/background_task_executor.h index 52fd780fb67..5547d3e4fd1 100644 --- a/frameworks/base/thread/background_task_executor.h +++ b/frameworks/base/thread/background_task_executor.h @@ -23,6 +23,11 @@ namespace OHOS::Ace { +enum class BgTaskPriority { + DEFAULT, + LOW, +}; + class BackgroundTaskExecutor { ACE_DISALLOW_COPY_AND_MOVE(BackgroundTaskExecutor); @@ -31,8 +36,8 @@ public: static BackgroundTaskExecutor& GetInstance(); - bool PostTask(Task&& task); - bool PostTask(const Task& task); + bool PostTask(Task&& task, BgTaskPriority priority = BgTaskPriority::DEFAULT); + bool PostTask(const Task& task, BgTaskPriority priority = BgTaskPriority::DEFAULT); void TriggerGarbageCollection(); @@ -46,6 +51,7 @@ private: std::mutex mutex_; std::condition_variable condition_; std::list tasks_; + std::list lowPriorityTasks_; std::list threads_; size_t currentThreadNum_ { 0 }; size_t maxThreadNum_ { 0 }; diff --git a/frameworks/core/image/image_loader.cpp b/frameworks/core/image/image_loader.cpp index 0989a4dfa40..427b41b6b5c 100644 --- a/frameworks/core/image/image_loader.cpp +++ b/frameworks/core/image/image_loader.cpp @@ -23,6 +23,7 @@ #include "base/network/download_manager.h" #include "base/resource/ace_res_config.h" #include "base/resource/asset_manager.h" +#include "base/thread/background_task_executor.h" #include "base/utils/string_utils.h" #include "core/common/ace_application_info.h" #include "core/common/ace_engine.h" @@ -53,16 +54,6 @@ char* realpath(const char* path, char* resolved_path) } // namespace -void ImageLoader::CacheResizedImage(const sk_sp& image, const std::string& key) -{ -#if !defined(WINDOWS_PLATFORM) and !defined(MAC_PLATFORM) - auto data = image->encodeToData(SkEncodedImageFormat::kPNG, 100); - if (data) { - ImageCache::WriteCacheFile(key, data->data(), data->size()); - } -#endif -} - std::string ImageLoader::RemovePathHead(const std::string& uri) { auto iter = uri.find_first_of(':'); @@ -164,7 +155,7 @@ sk_sp FileImageLoader::LoadImageData( .append(bundleName) .append("/files/") // infix of absolute path .append(filePath.substr(4)); // 4 is the length of "app/" from "internal://app/" - }\ + } if (filePath.length() > PATH_MAX) { LOGE("src path is too long"); return nullptr; @@ -207,8 +198,12 @@ sk_sp DataProviderImageLoader::LoadImageData( return nullptr; } auto imageData = dataRes->GetData(); - ImageCache::WriteCacheFile(src, imageData.data(), imageData.size()); - return SkData::MakeWithCopy(imageData.data(), imageData.size()); + sk_sp data = SkData::MakeWithCopy(imageData.data(), imageData.size()); + BackgroundTaskExecutor::GetInstance().PostTask( + [ src, imgData = std::move(imageData) ] () { + ImageCache::WriteCacheFile(src, imgData.data(), imgData.size()); + }, BgTaskPriority::LOW); + return data; } sk_sp AssetImageLoader::LoadImageData( @@ -295,17 +290,10 @@ sk_sp NetworkImageLoader::LoadImageData( } sk_sp data = SkData::MakeWithCopy(imageData.data(), imageData.size()); // 3. write it into file cache. - auto pipelineContext = context.Upgrade(); - if (!pipelineContext) { - LOGE("invalid pipeline context"); - return nullptr; - } - pipelineContext->GetTaskExecutor()->PostTask( + BackgroundTaskExecutor::GetInstance().PostTask( [ uri, imgData = std::move(imageData) ] () { ImageCache::WriteCacheFile(uri, imgData.data(), imgData.size()); - }, - TaskExecutor::TaskType::IO); - + }, BgTaskPriority::LOW); return data; } diff --git a/frameworks/core/image/image_loader.h b/frameworks/core/image/image_loader.h index 32b167939fc..0b249de5092 100644 --- a/frameworks/core/image/image_loader.h +++ b/frameworks/core/image/image_loader.h @@ -40,7 +40,6 @@ public: static std::string RemovePathHead(const std::string& uri); static RefPtr CreateImageLoader(const ImageSourceInfo& imageSourceInfo); - static void CacheResizedImage(const sk_sp& image, const std::string& key); static sk_sp LoadDataFromCachedFile(const std::string& uri); }; diff --git a/frameworks/core/image/image_provider.cpp b/frameworks/core/image/image_provider.cpp index d1be3ab3a39..b3b734d26ca 100644 --- a/frameworks/core/image/image_provider.cpp +++ b/frameworks/core/image/image_provider.cpp @@ -363,11 +363,16 @@ sk_sp ImageProvider::ApplySizeToSkImage( bool needCacheResizedImageFile = (1.0 * dstWidth * dstHeight) / (rawImage->width() * rawImage->height()) < RESIZE_MAX_PROPORTION; if (needCacheResizedImageFile && !srcKey.empty()) { - auto data = scaledImage->encodeToData(SkEncodedImageFormat::kPNG, 100); - if (data) { - LOGD("write cache file: %{private}s", srcKey.c_str()); - ImageCache::WriteCacheFile(srcKey, data->data(), data->size()); - } + BackgroundTaskExecutor::GetInstance().PostTask( + [ srcKey, scaledImage ] () { + LOGI("write png cache file: %{private}s", srcKey.c_str()); + auto data = scaledImage->encodeToData(SkEncodedImageFormat::kPNG, 100); + if (!data) { + LOGI("encode cache image into cache file failed."); + return; + } + ImageCache::WriteCacheFile(srcKey, data->data(), data->size()); + }, BgTaskPriority::LOW); } return scaledImage; } -- Gitee