MemStick screen: Call free_disk_space from async tasks

See #19522
This commit is contained in:
Henrik Rydgård 2024-10-11 11:55:27 +02:00
parent 3f3fd5bf64
commit 0b2f85eaad
13 changed files with 65 additions and 30 deletions

View File

@ -5,4 +5,5 @@
#include "Common/File/Path.h"
// If this fails, false is returned and space is negative.
// Try to avoid calling this from the main thread, if possible. Can be SLOW.
bool free_disk_space(const Path &path, int64_t &space);

View File

@ -130,6 +130,6 @@ bool BlobFileSystem::RemoveFile(const std::string &filename) {
return false;
}
u64 BlobFileSystem::FreeSpace(const std::string &path) {
u64 BlobFileSystem::FreeDiskSpace(const std::string &path) {
return 0;
}

View File

@ -52,7 +52,7 @@ public:
bool RmDir(const std::string &dirname) override;
int RenameFile(const std::string &from, const std::string &to) override;
bool RemoveFile(const std::string &filename) override;
u64 FreeSpace(const std::string &path) override;
u64 FreeDiskSpace(const std::string &path) override;
bool ComputeRecursiveDirSizeIfFast(const std::string &path, int64_t *size) override { return false; }

View File

@ -871,7 +871,7 @@ std::vector<PSPFileInfo> DirectoryFileSystem::GetDirListing(const std::string &p
return ReplayApplyDiskListing(myVector, CoreTiming::GetGlobalTimeUs());
}
u64 DirectoryFileSystem::FreeSpace(const std::string &path) {
u64 DirectoryFileSystem::FreeDiskSpace(const std::string &path) {
int64_t result = 0;
if (free_disk_space(GetLocalPath(path), result)) {
return ReplayApplyDisk64(ReplayAction::FREESPACE, (uint64_t)result, CoreTiming::GetGlobalTimeUs());

View File

@ -83,7 +83,7 @@ public:
int RenameFile(const std::string &from, const std::string &to) override;
bool RemoveFile(const std::string &filename) override;
FileSystemFlags Flags() override { return flags; }
u64 FreeSpace(const std::string &path) override;
u64 FreeDiskSpace(const std::string &path) override;
bool ComputeRecursiveDirSizeIfFast(const std::string &path, int64_t *size) override;
@ -129,7 +129,7 @@ public:
int RenameFile(const std::string &from, const std::string &to) override;
bool RemoveFile(const std::string &filename) override;
FileSystemFlags Flags() override { return FileSystemFlags::FLASH; }
u64 FreeSpace(const std::string &path) override { return 0; }
u64 FreeDiskSpace(const std::string &path) override { return 0; }
bool ComputeRecursiveDirSizeIfFast(const std::string &path, int64_t *size) override { return false; }

View File

@ -145,7 +145,7 @@ public:
virtual int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) = 0;
virtual PSPDevType DevType(u32 handle) = 0;
virtual FileSystemFlags Flags() = 0;
virtual u64 FreeSpace(const std::string &path) = 0;
virtual u64 FreeDiskSpace(const std::string &path) = 0;
virtual bool ComputeRecursiveDirSizeIfFast(const std::string &path, int64_t *size) = 0;
};
@ -175,7 +175,7 @@ public:
int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) override { return SCE_KERNEL_ERROR_ERRNO_FUNCTION_NOT_SUPPORTED; }
PSPDevType DevType(u32 handle) override { return PSPDevType::INVALID; }
FileSystemFlags Flags() override { return FileSystemFlags::NONE; }
u64 FreeSpace(const std::string &path) override { return 0; }
u64 FreeDiskSpace(const std::string &path) override { return 0; }
bool ComputeRecursiveDirSizeIfFast(const std::string &path, int64_t *size) override { return false; }
};

View File

@ -44,7 +44,7 @@ public:
int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) override;
PSPDevType DevType(u32 handle) override;
FileSystemFlags Flags() override;
u64 FreeSpace(const std::string &path) override { return 0; }
u64 FreeDiskSpace(const std::string &path) override { return 0; }
size_t WriteFile(u32 handle, const u8 *pointer, s64 size) override;
size_t WriteFile(u32 handle, const u8 *pointer, s64 size, int &usec) override;
@ -146,7 +146,7 @@ public:
return isoFileSystem_->DevType(handle);
}
FileSystemFlags Flags() override { return isoFileSystem_->Flags(); }
u64 FreeSpace(const std::string &path) override { return isoFileSystem_->FreeSpace(path); }
u64 FreeDiskSpace(const std::string &path) override { return isoFileSystem_->FreeDiskSpace(path); }
size_t WriteFile(u32 handle, const u8 *pointer, s64 size) override {
return isoFileSystem_->WriteFile(handle, pointer, size);

View File

@ -606,20 +606,18 @@ int MetaFileSystem::ReadEntireFile(const std::string &filename, std::vector<u8>
return 0;
}
u64 MetaFileSystem::FreeSpace(const std::string &path)
{
u64 MetaFileSystem::FreeDiskSpace(const std::string &path) {
std::lock_guard<std::recursive_mutex> guard(lock);
std::string of;
IFileSystem *system;
int error = MapFilePath(path, of, &system);
if (error == 0)
return system->FreeSpace(of);
return system->FreeDiskSpace(of);
else
return 0;
}
void MetaFileSystem::DoState(PointerWrap &p)
{
void MetaFileSystem::DoState(PointerWrap &p) {
std::lock_guard<std::recursive_mutex> guard(lock);
auto s = p.Section("MetaFileSystem", 1);
@ -634,8 +632,7 @@ void MetaFileSystem::DoState(PointerWrap &p)
u32 n = (u32) fileSystems.size();
Do(p, n);
bool skipPfat0 = false;
if (n != (u32) fileSystems.size())
{
if (n != (u32) fileSystems.size()) {
if (n == (u32) fileSystems.size() - 1) {
skipPfat0 = true;
} else {

View File

@ -127,7 +127,7 @@ public:
int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) override;
PSPDevType DevType(u32 handle) override;
FileSystemFlags Flags() override { return FileSystemFlags::NONE; }
u64 FreeSpace(const std::string &path) override;
u64 FreeDiskSpace(const std::string &path) override;
// Convenience helper - returns < 0 on failure.
int ReadEntireFile(const std::string &filename, std::vector<u8> &data, bool quiet = false);

View File

@ -44,7 +44,7 @@ public:
PSPDevType DevType(u32 handle) override;
std::vector<PSPFileInfo> GetDirListing(const std::string &path, bool *exists = nullptr) override;
FileSystemFlags Flags() override { return FileSystemFlags::UMD; }
u64 FreeSpace(const std::string &path) override { return 0; }
u64 FreeDiskSpace(const std::string &path) override { return 0; }
// unsupported operations
size_t WriteFile(u32 handle, const u8 *pointer, s64 size) override;

View File

@ -103,7 +103,7 @@ static void MemoryStick_CalcInitialFree() {
AndroidJNIThreadContext jniContext;
memstickInitialFree = pspFileSystem.FreeSpace("ms0:/") + pspFileSystem.ComputeRecursiveDirectorySize("ms0:/PSP/SAVEDATA/");
memstickInitialFree = pspFileSystem.FreeDiskSpace("ms0:/") + pspFileSystem.ComputeRecursiveDirectorySize("ms0:/PSP/SAVEDATA/");
std::unique_lock<std::mutex> guard(freeCalcMutex);
freeCalcStatus = FreeCalcStatus::DONE;
@ -122,10 +122,12 @@ static void MemoryStick_WaitInitialFree() {
}
u64 MemoryStick_FreeSpace() {
NOTICE_LOG(Log::IO, "Calculated free disk space");
MemoryStick_WaitInitialFree();
const CompatFlags &flags = PSP_CoreParameter().compat.flags();
u64 realFreeSpace = pspFileSystem.FreeSpace("ms0:/");
u64 realFreeSpace = pspFileSystem.FreeDiskSpace("ms0:/");
// Cap the memory stick size to avoid math errors when old games get sizes that were
// not planned for back then (even though 2GB cards were available.)

View File

@ -470,6 +470,14 @@ ConfirmMemstickMoveScreen::~ConfirmMemstickMoveScreen() {
moveDataTask_->BlockUntilReady();
delete moveDataTask_;
}
if (oldSpaceTask_) {
oldSpaceTask_->BlockUntilReady();
delete oldSpaceTask_;
}
if (newSpaceTask_) {
newSpaceTask_->BlockUntilReady();
delete newSpaceTask_;
}
}
void ConfirmMemstickMoveScreen::CreateViews() {
@ -479,7 +487,7 @@ void ConfirmMemstickMoveScreen::CreateViews() {
root_ = new LinearLayout(ORIENT_HORIZONTAL);
Path oldMemstickFolder = g_Config.memStickDirectory;
Path &oldMemstickFolder = g_Config.memStickDirectory;
Spacer *spacerColumn = new Spacer(new LinearLayoutParams(20.0, FILL_PARENT, 0.0f));
ViewGroup *leftColumn = new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(1.0));
@ -488,18 +496,20 @@ void ConfirmMemstickMoveScreen::CreateViews() {
root_->Add(leftColumn);
root_->Add(rightColumn);
int64_t freeSpaceNew;
int64_t freeSpaceOld;
free_disk_space(newMemstickFolder_, freeSpaceNew);
free_disk_space(oldMemstickFolder, freeSpaceOld);
leftColumn->Add(new TextView(ms->T("Selected PSP Data Folder"), ALIGN_LEFT, false));
if (!initialSetup_) {
leftColumn->Add(new NoticeView(NoticeLevel::WARN, ms->T("PPSSPP will restart after the change"), ""));
}
leftColumn->Add(new TextView(newMemstickFolder_.ToVisualString(), ALIGN_LEFT, false));
std::string newFreeSpaceText = std::string(ms->T("Free space")) + ": " + FormatSpaceString(freeSpaceNew);
leftColumn->Add(new TextView(newFreeSpaceText, ALIGN_LEFT, false));
newFreeSpaceView_ = leftColumn->Add(new TextView(ms->T("Free space"), ALIGN_LEFT, false));
newSpaceTask_ = Promise<SpaceResult *>::Spawn(&g_threadManager, [&]() -> SpaceResult * {
int64_t freeSpaceNew;
free_disk_space(newMemstickFolder_, freeSpaceNew);
return new SpaceResult{ freeSpaceNew };
}, TaskType::IO_BLOCKING, TaskPriority::HIGH);
if (existingFilesInNewFolder_) {
leftColumn->Add(new NoticeView(NoticeLevel::SUCCESS, ms->T("Already contains PSP data"), ""));
if (!moveData_) {
@ -511,11 +521,15 @@ void ConfirmMemstickMoveScreen::CreateViews() {
}
if (!oldMemstickFolder.empty()) {
std::string oldFreeSpaceText = std::string(ms->T("Free space")) + ": " + FormatSpaceString(freeSpaceOld);
oldSpaceTask_ = Promise<SpaceResult *>::Spawn(&g_threadManager, [&]() -> SpaceResult * {
int64_t freeSpaceOld;
free_disk_space(oldMemstickFolder, freeSpaceOld);
return new SpaceResult{ freeSpaceOld };
}, TaskType::IO_BLOCKING, TaskPriority::HIGH);
rightColumn->Add(new TextView(std::string(ms->T("Current")) + ":", ALIGN_LEFT, false));
rightColumn->Add(new TextView(oldMemstickFolder.ToVisualString(), ALIGN_LEFT, false));
rightColumn->Add(new TextView(oldFreeSpaceText, ALIGN_LEFT, false));
oldFreeSpaceView_ = rightColumn->Add(new TextView(ms->T("Free space"), ALIGN_LEFT, false));
}
if (moveDataTask_) {
@ -567,6 +581,19 @@ void ConfirmMemstickMoveScreen::update() {
moveDataTask_ = nullptr;
}
}
if (newSpaceTask_ && newFreeSpaceView_) {
SpaceResult *result = newSpaceTask_->Poll();
newFreeSpaceView_->SetText(std::string(ms->T("Free space")) + ": " + FormatSpaceString(result->bytesFree));
delete newSpaceTask_;
newSpaceTask_ = nullptr;
}
if (oldSpaceTask_ && oldFreeSpaceView_) {
SpaceResult *result = oldSpaceTask_->Poll();
oldFreeSpaceView_->SetText(std::string(ms->T("Free space")) + ": " + FormatSpaceString(result->bytesFree));
delete oldSpaceTask_;
oldSpaceTask_ = nullptr;
}
}
UI::EventReturn ConfirmMemstickMoveScreen::OnConfirm(UI::EventParams &params) {

View File

@ -93,6 +93,10 @@ private:
#endif
};
struct SpaceResult {
int64_t bytesFree;
};
class ConfirmMemstickMoveScreen : public UIDialogScreenWithBackground {
public:
ConfirmMemstickMoveScreen(const Path &newMemstickFolder, bool initialSetup);
@ -121,8 +125,12 @@ private:
MoveProgressReporter progressReporter_;
UI::TextView *progressView_ = nullptr;
UI::TextView *newFreeSpaceView_ = nullptr;
UI::TextView *oldFreeSpaceView_ = nullptr;
Promise<MoveResult *> *moveDataTask_ = nullptr;
Promise<SpaceResult *> *oldSpaceTask_ = nullptr;
Promise<SpaceResult *> *newSpaceTask_ = nullptr;
std::string error_;
};