ksys/res: Implement ResourceMgrTask cache clear functions

This commit is contained in:
Léo Lam 2020-10-11 21:42:10 +02:00
parent 1c9d5781ae
commit 0a0d287e37
No known key found for this signature in database
GPG Key ID: 0DF30F9081000741
6 changed files with 82 additions and 8 deletions

View File

@ -90925,8 +90925,8 @@
0x0000007101209b08,res::ResourceMgrTask::submitUnloadRequest,332,
0x0000007101209dd8,res::ResourceMgrTask::a,128,_ZN4ksys3res15ResourceMgrTask12registerUnitEPNS0_12ResourceUnitE
0x0000007101209e58,res::ResourceMgrTask::b,128,_ZN4ksys3res15ResourceMgrTask14deregisterUnitEPNS0_12ResourceUnitE
0x0000007101209ed8,res::ResourceMgrTask::clearCache,464,
0x000000710120a0a8,res::ResourceMgrTask::clearCacheForSync,524,
0x0000007101209ed8,res::ResourceMgrTask::clearCache,464,_ZN4ksys3res15ResourceMgrTask17requestClearCacheEPPNS0_12ResourceUnitEPNS_4util4TaskE
0x000000710120a0a8,res::ResourceMgrTask::clearCacheForSync,524,_ZN4ksys3res15ResourceMgrTask24requestClearCacheForSyncEPPNS0_12ResourceUnitEbb
0x000000710120a2b4,res::ResourceMgrTask::n,144,_ZN4ksys3res15ResourceMgrTask10deleteUnitERPNS0_12ResourceUnitEb
0x000000710120a344,res::ResourceMgrTask::deleteUnit,400,_ZN4ksys3res15ResourceMgrTask17requestDeleteUnitEPPNS0_12ResourceUnitE
0x000000710120a4d4,nullsub_4699,4,_ZN4ksys3res17MemoryTaskRequestD2Ev

Can't render this file because it is too large.

View File

@ -149,7 +149,7 @@ void Cache::removeUnitAndClearCache_(ResourceUnit* unit) {
unit->mStatusFlags.reset(ResourceUnit::StatusFlag::_20000);
if (unit->isStatusFlag8000Set()) {
ResourceMgrTask::instance()->deregisterUnit(unit);
ResourceMgrTask::instance()->requestClearCache(unit);
ResourceMgrTask::instance()->requestClearCache(&unit);
}
}

View File

@ -247,6 +247,80 @@ void ResourceMgrTask::deregisterUnit(ResourceUnit* unit) {
}
}
void ResourceMgrTask::requestClearCache(ResourceUnit** p_unit, util::Task* task) {
if (!p_unit || !*p_unit || !(*p_unit)->isStatusFlag8000Set()) {
stubbedLogFunction();
return;
}
if ((*p_unit)->getRefCount() > 0 || (*p_unit)->isStatus1() || (*p_unit)->isStatusFlag10000Set())
return;
(*p_unit)->setStatusFlag10000();
{
ControlTaskRequest req;
req.mHasHandle = true;
req.mSynchronous = false;
req.mLaneId = u8(LaneId::_4);
req.mThread = mResourceControlThread;
req.mDelegate = &mUnitClearCacheForSyncFn.fn;
req.mPostRunCallback = &mUnitClearCacheForSyncFn.cb;
req.mUserData = *p_unit;
req.mName = "ClearCache";
if (task)
task->submitRequest(req);
else
(*p_unit)->mTask3.submitRequest(req);
}
*p_unit = nullptr;
}
void ResourceMgrTask::requestClearCacheForSync(ResourceUnit** p_unit, bool clear_immediately,
bool delete_immediately) {
if (!p_unit || !*p_unit || !(*p_unit)->isStatusFlag8000Set()) {
goto fail;
}
if ((*p_unit)->isStatus1() || !(*p_unit)->mCache || (*p_unit)->getRefCount() > 0)
return;
if ((*p_unit)->isStatusFlag10000Set()) {
fail:
stubbedLogFunction();
return;
}
(*p_unit)->setStatusFlag10000();
if (clear_immediately) {
(*p_unit)->removeTask3FromQueue();
(*p_unit)->clearCacheForSync(true);
(*p_unit)->clearCache(nullptr);
static_cast<void>((*p_unit)->getStatus());
ResourceUnit* ptr = *p_unit;
if (delete_immediately)
deleteUnit(ptr, true);
else
requestDeleteUnit(&ptr);
} else {
ControlTaskRequest req;
req.mHasHandle = true;
req.mSynchronous = true;
req.mLaneId = u8(LaneId::_4);
req.mThread = mResourceControlThread;
req.mDelegate = &mUnitClearCacheForSyncFn.fn;
req.mUserData = *p_unit;
req.mName = "ClearCache(ForSync)";
(*p_unit)->mTask3.submitRequest(req);
}
*p_unit = nullptr;
}
#ifdef MATCHING_HACK_NX_CLANG
[[gnu::noinline]]
#endif
void ResourceMgrTask::deleteUnit(ResourceUnit*& unit, bool sync) {
if (!unit)
return;

View File

@ -146,8 +146,8 @@ public:
void registerUnit(ResourceUnit* unit);
void deregisterUnit(ResourceUnit* unit);
void requestClearCache(ResourceUnit*& unit, void* x = nullptr);
void requestClearCacheForSync(ResourceUnit*& unit, bool clear_immediately,
void requestClearCache(ResourceUnit** p_unit, util::Task* task = nullptr);
void requestClearCacheForSync(ResourceUnit** p_unit, bool clear_immediately,
bool delete_immediately);
void deleteUnit(ResourceUnit*& unit, bool sync);

View File

@ -212,10 +212,10 @@ private:
void requestPrepareLoad(util::TaskPostRunResult* result, const util::TaskPostRunContext& ctx);
void unloadForSync();
void clearCacheForSync();
void clearCacheForSync(bool x);
void unload();
void clearCache();
void clearCache(void* x);
void requestClearCache(util::TaskPostRunResult* result, const util::TaskPostRunContext& ctx);
sead::TypedBitFlag<CacheFlag> mCacheFlags;

View File

@ -77,7 +77,7 @@ void OverlayArena::clearUnits() {
res::ResourceUnit* unit = std::addressof(*it);
res::stubbedLogFunction();
res::ResourceMgrTask::instance()->deregisterUnit(unit);
res::ResourceMgrTask::instance()->requestClearCacheForSync(unit, true, false);
res::ResourceMgrTask::instance()->requestClearCacheForSync(&unit, true, false);
}
res::stubbedLogFunction();
}