mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-11 05:26:24 +02:00
Get rid of the PrioritizedWorkQueue. Instead just queue tasks on the ThreadManager.
This commit is contained in:
1 parent
34f8fc557f
commit
446c2c027e
17 files changed
+102
-293
No files matched your search
+28
-52
@@ -23,7 +23,7 @@
|
||||
#include <algorithm>
|
||||
|
||||
#include "Common/GPU/thin3d.h"
|
||||
#include "Common/Thread/PrioritizedWorkQueue.h"
|
||||
#include "Common/Thread/ThreadManager.h"
|
||||
#include "Common/File/VFS/VFS.h"
|
||||
#include "Common/File/FileUtil.h"
|
||||
#include "Common/File/Path.h"
|
||||
@@ -214,8 +214,8 @@ bool GameInfo::LoadFromPath(const Path &gamePath) {
|
||||
|
||||
std::shared_ptr<FileLoader> GameInfo::GetFileLoader() {
|
||||
if (filePath_.empty()) {
|
||||
// Happens when workqueue tries to figure out priorities in PrioritizedWorkQueue::Pop(),
|
||||
// because priority() calls GetFileLoader()... gnarly.
|
||||
// Happens when workqueue tries to figure out priorities,
|
||||
// because Priority() calls GetFileLoader()... gnarly.
|
||||
return fileLoader;
|
||||
}
|
||||
if (!fileLoader) {
|
||||
@@ -331,7 +331,7 @@ static bool ReadVFSToString(const char *filename, std::string *contents, std::mu
|
||||
}
|
||||
|
||||
|
||||
class GameInfoWorkItem : public PrioritizedWorkQueueItem {
|
||||
class GameInfoWorkItem : public Task {
|
||||
public:
|
||||
GameInfoWorkItem(const Path &gamePath, std::shared_ptr<GameInfo> &info)
|
||||
: gamePath_(gamePath), info_(info) {
|
||||
@@ -341,15 +341,18 @@ public:
|
||||
info_->DisposeFileLoader();
|
||||
}
|
||||
|
||||
void run() override {
|
||||
void Run() override {
|
||||
// NOTE! DO NOT early-return from this, always use "goto done". It's essential
|
||||
// that we trigger the event.
|
||||
|
||||
if (!info_->LoadFromPath(gamePath_)) {
|
||||
info_->pending = false;
|
||||
return;
|
||||
goto done;
|
||||
}
|
||||
// In case of a remote file, check if it actually exists before locking.
|
||||
if (!info_->GetFileLoader()->Exists()) {
|
||||
info_->pending = false;
|
||||
return;
|
||||
goto done;
|
||||
}
|
||||
|
||||
info_->working = true;
|
||||
@@ -371,10 +374,8 @@ public:
|
||||
if (pbp.IsELF()) {
|
||||
goto handleELF;
|
||||
}
|
||||
ERROR_LOG(LOADER, "invalid pbp '%s'\n", pbpLoader->GetPath().ToVisualString().c_str());
|
||||
info_->pending = false;
|
||||
info_->working = false;
|
||||
return;
|
||||
ERROR_LOG(LOADER, "invalid pbp '%s'\n", pbpLoader->GetPath().c_str());
|
||||
goto done;
|
||||
}
|
||||
|
||||
// First, PARAM.SFO.
|
||||
@@ -541,15 +542,11 @@ handleELF:
|
||||
// few files.
|
||||
auto fl = info_->GetFileLoader();
|
||||
if (!fl) {
|
||||
info_->pending = false;
|
||||
info_->working = false;
|
||||
return; // Happens with UWP currently, TODO...
|
||||
goto done;
|
||||
}
|
||||
BlockDevice *bd = constructBlockDevice(info_->GetFileLoader().get());
|
||||
if (!bd) {
|
||||
info_->pending = false;
|
||||
info_->working = false;
|
||||
return; // nothing to do here..
|
||||
goto done;
|
||||
}
|
||||
ISOFileSystem umd(&handles, bd);
|
||||
|
||||
@@ -629,12 +626,14 @@ handleELF:
|
||||
info_->installDataSize = info_->GetInstallDataSizeInBytes();
|
||||
}
|
||||
|
||||
done:
|
||||
info_->pending = false;
|
||||
info_->working = false;
|
||||
info_->readyEvent.Notify();
|
||||
// INFO_LOG(SYSTEM, "Completed writing info for %s", info_->GetTitle().c_str());
|
||||
}
|
||||
|
||||
float priority() override {
|
||||
float Priority() override {
|
||||
auto fl = info_->GetFileLoader();
|
||||
if (fl && fl->IsRemote()) {
|
||||
// Increase the value so remote info loads after non-remote.
|
||||
@@ -649,7 +648,7 @@ private:
|
||||
DISALLOW_COPY_AND_ASSIGN(GameInfoWorkItem);
|
||||
};
|
||||
|
||||
GameInfoCache::GameInfoCache() : gameInfoWQ_(nullptr) {
|
||||
GameInfoCache::GameInfoCache() {
|
||||
Init();
|
||||
}
|
||||
|
||||
@@ -658,28 +657,15 @@ GameInfoCache::~GameInfoCache() {
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
void GameInfoCache::Init() {
|
||||
gameInfoWQ_ = new PrioritizedWorkQueue();
|
||||
ProcessWorkQueueOnThreadWhile(gameInfoWQ_);
|
||||
}
|
||||
void GameInfoCache::Init() {}
|
||||
|
||||
void GameInfoCache::Shutdown() {
|
||||
CancelAll();
|
||||
|
||||
if (gameInfoWQ_) {
|
||||
StopProcessingWorkQueue(gameInfoWQ_);
|
||||
delete gameInfoWQ_;
|
||||
gameInfoWQ_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void GameInfoCache::Clear() {
|
||||
CancelAll();
|
||||
|
||||
if (gameInfoWQ_) {
|
||||
gameInfoWQ_->Flush();
|
||||
gameInfoWQ_->WaitUntilDone();
|
||||
}
|
||||
info_.clear();
|
||||
}
|
||||
|
||||
@@ -706,31 +692,21 @@ void GameInfoCache::FlushBGs() {
|
||||
}
|
||||
|
||||
void GameInfoCache::PurgeType(IdentifiedFileType fileType) {
|
||||
if (gameInfoWQ_)
|
||||
gameInfoWQ_->Flush();
|
||||
restart:
|
||||
for (auto iter = info_.begin(); iter != info_.end(); iter++) {
|
||||
for (auto iter = info_.begin(); iter != info_.end();) {
|
||||
auto &info = iter->second;
|
||||
if (!info->working && info->fileType == fileType) {
|
||||
info_.erase(iter);
|
||||
goto restart;
|
||||
info->readyEvent.Wait();
|
||||
if (info->fileType == fileType) {
|
||||
iter = info_.erase(iter);
|
||||
} else {
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GameInfoCache::WaitUntilDone(std::shared_ptr<GameInfo> &info) {
|
||||
while (info->pending) {
|
||||
if (gameInfoWQ_->WaitUntilDone(false)) {
|
||||
// A true return means everything finished, so bail out.
|
||||
// This way even if something gets stuck, we won't hang.
|
||||
break;
|
||||
}
|
||||
|
||||
// Otherwise, wait again if it's not done...
|
||||
}
|
||||
info->readyEvent.Wait();
|
||||
}
|
||||
|
||||
|
||||
// Runs on the main thread. Only call from render() and similar, not update()!
|
||||
// Can also be called from the audio thread for menu background music.
|
||||
std::shared_ptr<GameInfo> GameInfoCache::GetInfo(Draw::DrawContext *draw, const Path &gamePath, int wantFlags) {
|
||||
@@ -776,11 +752,11 @@ std::shared_ptr<GameInfo> GameInfoCache::GetInfo(Draw::DrawContext *draw, const
|
||||
}
|
||||
|
||||
GameInfoWorkItem *item = new GameInfoWorkItem(gamePath, info);
|
||||
gameInfoWQ_->Add(item);
|
||||
g_threadManager.EnqueueTask(item);
|
||||
|
||||
// Don't re-insert if we already have it.
|
||||
if (info_.find(pathStr) == info_.end())
|
||||
info_[pathStr] = std::shared_ptr<GameInfo>(info);
|
||||
info_[pathStr] = info;
|
||||
return info;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user