ksys/res: Implement more ResourceMgrTask and OverlayArena functions

This commit is contained in:
Léo Lam 2020-10-11 12:34:15 +02:00
parent fc0d0ddaf7
commit 1c9d5781ae
No known key found for this signature in database
GPG Key ID: 0DF30F9081000741
14 changed files with 874 additions and 105 deletions

View File

@ -90685,26 +90685,26 @@
0x00000071011fc9f4,OverlayArenaSystem::Struct1::destroy,268,
0x00000071011fcb00,OverlayArenaSystem::Struct1::dtorDelete,64,_ZN4ksys12OverlayArenaD0Ev
0x00000071011fcb40,OverlayArena::makeHeap,384,_ZN4ksys12OverlayArena4initERKNS0_7InitArgE?
0x00000071011fccc0,nullsub_4690,4,
0x00000071011fccc4,sub_71011FCCC4,48,
0x00000071011fccf4,OverlayArenaSystem::Struct1::callResMgrClearCacheForSync,180,
0x00000071011fcda8,OverlayArenaSystem::Struct1::x,12,
0x00000071011fcdb4,sub_71011FCDB4,16,
0x00000071011fcdc4,sub_71011FCDC4,8,
0x00000071011fcdcc,OverlayArenaSystem::Struct1::c,12,
0x00000071011fcdd8,sub_71011FCDD8,12,
0x00000071011fcde4,OverlayArena::hasIssues,168,
0x00000071011fccc0,nullsub_4690,4,_ZN4ksys12OverlayArena7stubbedEv
0x00000071011fccc4,sub_71011FCCC4,48,_ZN4ksys12OverlayArena11updateFlag8Eb
0x00000071011fccf4,OverlayArenaSystem::Struct1::callResMgrClearCacheForSync,180,_ZN4ksys12OverlayArena10clearUnitsEv
0x00000071011fcda8,OverlayArenaSystem::Struct1::x,12,_ZNK4ksys12OverlayArena10isFlag1SetEv
0x00000071011fcdb4,sub_71011FCDB4,16,_ZNK4ksys12OverlayArena10hasNoUnitsEv
0x00000071011fcdc4,sub_71011FCDC4,8,_ZNK4ksys12OverlayArena11getNumUnitsEv
0x00000071011fcdcc,OverlayArenaSystem::Struct1::c,12,_ZNK4ksys12OverlayArena11isFlag10SetEv
0x00000071011fcdd8,sub_71011FCDD8,12,_ZNK4ksys12OverlayArena10isFlag8SetEv
0x00000071011fcde4,OverlayArena::hasIssues,168,_ZNK4ksys12OverlayArena10checkIsOomEv
0x00000071011fce8c,OverlayArenaSystem::Struct1::setBloodyMoonReason,432,
0x00000071011fd03c,sub_71011FD03C,596,
0x00000071011fd290,OverlayArenaSystem::Struct1::makeDualHeap,320,
0x00000071011fd290,OverlayArenaSystem::Struct1::makeDualHeap,320,_ZN4ksys12OverlayArena12makeDualHeapEjRKN4sead14SafeStringBaseIcEENS1_4Heap13HeapDirectionEPNS_3res12ResourceUnitEb!
0x00000071011fd3d0,OverlayArenaSystem::Struct1::b,232,
0x00000071011fd4b8,sub_71011FD4B8,212,
0x00000071011fd58c,sub_71011FD58C,192,
0x00000071011fd64c,sub_71011FD64C,380,
0x00000071011fd7c8,OverlayArenaSystem::Struct1::a,160,
0x00000071011fd868,OverlayArenaSystem::Struct1::defragMemoryStuff,920,
0x00000071011fdc00,sub_71011FDC00,16,
0x00000071011fdc10,sub_71011FDC10,16,
0x00000071011fdc00,sub_71011FDC00,16,_ZN4ksys12OverlayArena7addSizeEi
0x00000071011fdc10,sub_71011FDC10,16,_ZN4ksys12OverlayArena8addSize2Ei
0x00000071011fdc20,OverlayArenaSystem::Struct1::calculateHeapSizeStuff,512,
0x00000071011fde20,OverlayArenaSystem::Struct1::y,364,
0x00000071011fdf8c,sub_71011FDF8C,648,
@ -90767,7 +90767,7 @@
0x000000710120130c,ResourceBase::callOnDestroy,12,_ZN4ksys3res8Resource9onDestroyEv
0x0000007101201318,ResourceBase::callParse,24,_ZN4ksys3res8Resource5parseEPNS0_7ContextEPN4sead4HeapE
0x0000007101201330,ResourceBase::callM5,32,_ZN4ksys3res8Resource8finalizeEv
0x0000007101201350,ResourceBase::callM6AndClearField30,48,_ZN4ksys3res8Resource13finishParsingEv
0x0000007101201350,ResourceBase::callM6AndClearField30,48,_ZN4ksys3res8Resource13finishParsingEPNS0_7ContextE
0x0000007101201380,ResourceBase::callM7,12,_ZN4ksys3res8Resource2m7Ev
0x000000710120138c,ResourceBase::doCreate,4,_ZN4ksys3res8Resource9doCreate_EPhjPN4sead4HeapE
0x0000007101201390,ResourceBase::onDestroy,4,_ZN4ksys3res8Resource10onDestroy_Ev
@ -90897,72 +90897,72 @@
0x0000007101206d74,res::ResourceMgrTask::calc_,288,
0x0000007101206e94,res::System::calc_,196,
0x0000007101206f58,res::ResourceMgrTask::oo,380,
0x00000071012070d4,res::ResourceMgrTask::isCompactionStopped,24,
0x00000071012070d4,res::ResourceMgrTask::isCompactionStopped,24,_ZNK4ksys3res15ResourceMgrTask19isCompactionStoppedEv
0x00000071012070ec,res::ResourceMgrTask::submitCalcRequest,36,
0x0000007101207110,res::ResourceMgrTask::postCalc,20,
0x0000007101207124,res::ResourceMgrTask::clearAllCaches,288,
0x0000007101207124,res::ResourceMgrTask::clearAllCaches,288,_ZN4ksys3res15ResourceMgrTask14clearAllCachesEPNS_12OverlayArenaE
0x0000007101207244,res::ResourceMgrTask::BinderArray::getTexHandleMgrArena,32,
0x0000007101207264,EventPlusString::RequestEx::dtor,24,_ZN4ksys3res18ControlTaskRequestD2Ev
0x000000710120727c,res::ResourceMgrTask::defragAllMemoryMgr,800,
0x000000710120759c,res::ResourceMgrTask::__auto7,20,
0x00000071012075b0,res::ResourceMgrTask::getDefragProgress,104,
0x000000710120759c,res::ResourceMgrTask::__auto7,20,_ZNK4ksys3res15ResourceMgrTask12isDefragDoneEv
0x00000071012075b0,res::ResourceMgrTask::getDefragProgress,104,_ZNK4ksys3res15ResourceMgrTask17getDefragProgressEv
0x00000071012076a8,res::ResourceMgrTask::getCacheIdx,956,
0x0000007101207a64,stringPathManipulationStuff,1284,
0x0000007101207f68,sub_7101207F68,680,
0x0000007101208210,res::ResourceMgrTask::__auto5,256,
0x0000007101208310,res::ResourceMgrTask::callMethodsOnThreads,96,
0x0000007101208370,res::ResourceMgrTask::__auto10,8,
0x0000007101208378,res::ResourceMgrTask::getMainFileDevice,16,
0x0000007101208388,res::ResourceMgrTask::getArchiveFileDev1,16,
0x00000071012083a8,res::ResourceMgrTask::__auto0,88,
0x000000710120842c,res::ResourceMgrTask::setField174Flag2000Or5000,36,
0x0000007101207f68,sub_7101207F68,680,_ZNK4sead8ObjArrayINS_14SafeStringBaseIcEEE12binarySearchEPKS2_?
0x0000007101208210,res::ResourceMgrTask::__auto5,256,_ZN4ksys3res15ResourceMgrTask11cancelTasksEv
0x0000007101208310,res::ResourceMgrTask::callMethodsOnThreads,96,_ZN4ksys3res15ResourceMgrTask24waitForTaskQueuesToEmptyEv
0x0000007101208370,res::ResourceMgrTask::__auto10,8,_ZNK4ksys3res15ResourceMgrTask35getNumActiveTasksOnResLoadingThreadEv
0x0000007101208378,res::ResourceMgrTask::getMainFileDevice,16,_ZNK4ksys3res15ResourceMgrTask23getOffsetReadFileDeviceEv
0x0000007101208388,res::ResourceMgrTask::getArchiveFileDev1,16,_ZN4ksys3res15ResourceMgrTask18getArchiveFileDev1Ev
0x00000071012083a8,res::ResourceMgrTask::__auto0,88,_ZN4ksys3res15ResourceMgrTask18controlField9c0d88Eb?
0x000000710120842c,res::ResourceMgrTask::setField174Flag2000Or5000,36,_ZN4ksys3res15ResourceMgrTask17setFlag2000Or5000Ei
0x0000007101208450,res::ResourceMgrTask::setSomePropertiesOnArgForLoad,960,
0x0000007101208810,res::ResourceMgrTask::getFactoryForExtensionAndFallBackToResBase,1008,
0x0000007101208c00,res::ResourceMgrTask::x,12,
0x0000007101208c00,res::ResourceMgrTask::x,12,_ZNK4ksys3res15ResourceMgrTask10isFlag4SetEv
0x0000007101208c0c,res::ResourceMgrTask::submitLoadRequest,1288,
0x0000007101209114,res::ResourceMgrTask::copyExtensionAndRemoveS,292,
0x0000007101209238,res::ResourceMgrTask::submitLoadForSyncRequest,2240,
0x0000007101209b08,res::ResourceMgrTask::submitUnloadRequest,332,
0x0000007101209dd8,res::ResourceMgrTask::a,128,
0x0000007101209e58,res::ResourceMgrTask::b,128,
0x0000007101209dd8,res::ResourceMgrTask::a,128,_ZN4ksys3res15ResourceMgrTask12registerUnitEPNS0_12ResourceUnitE
0x0000007101209e58,res::ResourceMgrTask::b,128,_ZN4ksys3res15ResourceMgrTask14deregisterUnitEPNS0_12ResourceUnitE
0x0000007101209ed8,res::ResourceMgrTask::clearCache,464,
0x000000710120a0a8,res::ResourceMgrTask::clearCacheForSync,524,
0x000000710120a2b4,res::ResourceMgrTask::n,144,
0x000000710120a344,res::ResourceMgrTask::deleteUnit,400,
0x000000710120a2b4,res::ResourceMgrTask::n,144,_ZN4ksys3res15ResourceMgrTask10deleteUnitERPNS0_12ResourceUnitEb
0x000000710120a344,res::ResourceMgrTask::deleteUnit,400,_ZN4ksys3res15ResourceMgrTask17requestDeleteUnitEPPNS0_12ResourceUnitE
0x000000710120a4d4,nullsub_4699,4,_ZN4ksys3res17MemoryTaskRequestD2Ev
0x000000710120a4d8,res::ResourceMgrTask::load,1292,
0x000000710120a9e4,canUseSdCard,8,
0x000000710120a9ec,return_0_0,8,
0x000000710120a9f4,res::ResourceMgrTask::dropSFromExtensionForBfevflBcamanimAndBarslist,756,
0x000000710120ace8,res::ResourceMgrTask::unloadSeadResource,84,
0x000000710120ad3c,res::ResourceMgrTask::getResourceSize,328,
0x000000710120ae84,res::ResourceMgrTask::insertIntoFileDeviceToPrefixMap,116,
0x000000710120aef8,res::ResourceMgrTask::eraseFromFileDeviceToPrefixMap,104,
0x000000710120af60,res::ResourceMgrTask::__auto3,164,
0x000000710120b004,res::ResourceMgrTask::__auto9,64,
0x000000710120b044,res::ResourceMgrTask::makeDualHeap,212,
0x000000710120a9e4,canUseSdCard,8,_ZNK4ksys3res15ResourceMgrTask12canUseSdCardEv
0x000000710120a9ec,return_0_0,8,_ZNK4ksys3res15ResourceMgrTask11returnFalseEv
0x000000710120a9f4,res::ResourceMgrTask::dropSFromExtensionForBfevflBcamanimAndBarslist,756,_ZNK4ksys3res15ResourceMgrTask26dropSFromExtensionIfNeededERKN4sead14SafeStringBaseIcEERNS2_22BufferedSafeStringBaseIcEEiS6_
0x000000710120ace8,res::ResourceMgrTask::unloadSeadResource,84,_ZN4ksys3res15ResourceMgrTask18unloadSeadResourceEPN4sead8ResourceE
0x000000710120ad3c,res::ResourceMgrTask::getResourceSize,328,_ZNK4ksys3res15ResourceMgrTask15getResourceSizeERKN4sead14SafeStringBaseIcEEPNS2_10FileDeviceE
0x000000710120ae84,res::ResourceMgrTask::insertIntoFileDeviceToPrefixMap,116,_ZN4ksys3res15ResourceMgrTask24registerFileDevicePrefixERNS0_16FileDevicePrefixE
0x000000710120aef8,res::ResourceMgrTask::eraseFromFileDeviceToPrefixMap,104,_ZN4ksys3res15ResourceMgrTask26deregisterFileDevicePrefixERNS0_16FileDevicePrefixE
0x000000710120af60,res::ResourceMgrTask::__auto3,164,_ZN4ksys3res15ResourceMgrTask27callStubbedFunctionOnArenasEv
0x000000710120b004,res::ResourceMgrTask::__auto9,64,_ZN4ksys3res15ResourceMgrTask25updateResourceArenasFlag8Ev
0x000000710120b044,res::ResourceMgrTask::makeDualHeap,212,_ZN4ksys3res15ResourceMgrTask15makeHeapForUnitERKNS1_11MakeHeapArgE!
0x000000710120b118,res::ResourceMgrTask::__auto4,96,
0x000000710120b178,res::ResourceMgrTask::clearCachesAndGetBinder,568,
0x000000710120b178,res::ResourceMgrTask::clearCachesAndGetBinder,568,_ZN4ksys3res15ResourceMgrTask21clearCachesAndGetUnitERKNS1_10GetUnitArgE
0x000000710120b3b0,nullsub_4700,4,
0x000000710120b3b4,res::ResourceMgrTask::setActorCreateInitialiserThreads,24,
0x000000710120b3cc,res::ResourceMgrTask::clearActorCreateInitialiserThreads,20,
0x000000710120b3e0,res::ResourceMgrTask::__auto11,76,
0x000000710120b42c,sub_710120B42C,60,
0x000000710120b468,res::ResourceMgrTask::getParallelSzsDecompressor,60,
0x000000710120b4a4,res::ResourceMgrTask::unlockSzsDecompressorCS,8,
0x000000710120b4ac,res::ResourceMgrTask::getYaz0UncompressedSize,248,
0x000000710120b3b4,res::ResourceMgrTask::setActorCreateInitialiserThreads,24,_ZN4ksys3res15ResourceMgrTask32setActorCreateInitializerThreadsERKNS1_35SetActorCreateInitializerThreadsArgE
0x000000710120b3cc,res::ResourceMgrTask::clearActorCreateInitialiserThreads,20,_ZN4ksys3res15ResourceMgrTask34clearActorCreateInitializerThreadsEv
0x000000710120b3e0,res::ResourceMgrTask::__auto11,76,_ZN4ksys3res15ResourceMgrTask12pauseThreadsEv
0x000000710120b42c,sub_710120B42C,60,_ZN4ksys3res15ResourceMgrTask13resumeThreadsEv
0x000000710120b468,res::ResourceMgrTask::getParallelSzsDecompressor,60,_ZN4ksys3res15ResourceMgrTask18getSzsDecompressorEv
0x000000710120b4a4,res::ResourceMgrTask::unlockSzsDecompressorCS,8,_ZN4ksys3res15ResourceMgrTask23unlockSzsDecompressorCSEv
0x000000710120b4ac,res::ResourceMgrTask::getYaz0UncompressedSize,248,_ZNK4ksys3res15ResourceMgrTask19getUncompressedSizeEPjRKN4sead14SafeStringBaseIcEEPNS3_10FileDeviceE
0x000000710120b5a4,nullsub_4701,4,
0x000000710120b5a8,res::ResourceMgrTask::setCompactionStopped,104,
0x000000710120b5a8,res::ResourceMgrTask::setCompactionStopped,104,_ZN4ksys3res15ResourceMgrTask20setCompactionStoppedEb?
0x000000710120b648,res::ResourceMgrTask::setStruct10OnTempResLoader,60,
0x000000710120b684,res::ResourceMgrTask::repairAllHandlesForSync,24,
0x000000710120b6ac,sub_710120B6AC,8,
0x000000710120b704,res::ResourceMgrTask::__auto8,80,
0x000000710120ba64,res::ResourceMgrTask::queueClearAllCaches,288,
0x000000710120bb84,res::ResourceMgrTask::alwaysReturnOne,8,
0x000000710120b6ac,sub_710120B6AC,8,_ZN4ksys3res15ResourceMgrTask11returnTrue1Ev
0x000000710120b704,res::ResourceMgrTask::__auto8,80,_ZN4ksys3res15ResourceMgrTask27clearCacheWithFileExtensionERKN4sead14SafeStringBaseIcEE
0x000000710120ba64,res::ResourceMgrTask::queueClearAllCaches,288,_ZN4ksys3res15ResourceMgrTask27clearAllCachesSynchronouslyEPNS_12OverlayArenaE
0x000000710120bb84,res::ResourceMgrTask::alwaysReturnOne,8,_ZN4ksys3res15ResourceMgrTask10returnTrueEv
0x000000710120bb8c,res::ResourceMgrTask::getHeapSizeForResLoad,1708,
0x000000710120c238,res::getRequiredBufferSizeForFile,424,
0x000000710120c3e0,res::ResourceMgrTask::y,336,
0x000000710120c530,res::ResourceMgrTask::removeOverlayArena,152,
0x000000710120c530,res::ResourceMgrTask::removeOverlayArena,152,_ZN4ksys3res15ResourceMgrTask18removeOverlayArenaEPNS_12OverlayArenaE
0x000000710120c6dc,res::ResourceMgrTask::checkDerivedRuntimeTypeInfo,288,
0x000000710120c7fc,res::ResourceMgrTask::getRuntimeTypeInfo,92,
0x000000710120c858,EventPlusString::RequestEx::rtti1,204,_ZNK4ksys3res18ControlTaskRequest27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE
@ -91060,7 +91060,7 @@
0x0000007101213278,res::texHandleMgrSetSomeFlags,24,
0x0000007101213290,return_1,8,_ZN4ksys3res18stubbedLogFunctionEv
0x0000007101213298,return_0_,8,_ZN4ksys3res11returnFalseEv
0x00000071012132a0,return_0_2,8,_ZN4ksys3res12returnFalse2Ev
0x00000071012132a0,return_0_2,8,_ZN4ksys3res12returnFalse2ERKN4sead14SafeStringBaseIcEE
0x00000071012132a8,nullsub_4703,4,
0x00000071012132ac,return_0__,8,
0x00000071012132b4,nullsub_4704,4,
@ -91070,7 +91070,7 @@
0x00000071012132c4,nullsub_4708,4,
0x00000071012132c8,nullsub_4709,4,
0x00000071012132cc,return_0,8,
0x00000071012132d4,return_8,8,
0x00000071012132d4,return_8,8,_ZN4ksys3res19getDefaultAlignmentEv
0x00000071012132dc,return1,16,
0x00000071012132ec,ArchiveRes::ctor,60,_ZN4ksys3res7ArchiveC1Ev
0x0000007101213328,ArchiveRes::dtor,4,_ZN4ksys3res7ArchiveD1Ev
@ -93239,7 +93239,7 @@
0x00000071012bc9d4,ResourceInfoContainer::dtor,20,_ZN4ksys3res21ResourceInfoContainerD1Ev
0x00000071012bc9e8,ResourceInfoContainer::dtorDelete,52,_ZN4ksys3res21ResourceInfoContainerD0Ev
0x00000071012bca1c,ResourceInfoContainer::loadSizeTable,500,_ZN4ksys3res21ResourceInfoContainer21loadResourceSizeTableEv?
0x00000071012bcc10,ResourceInfoContainer::getResourceSize,384,_ZN4ksys3res21ResourceInfoContainer15getResourceSizeERKN4sead14SafeStringBaseIcEE?
0x00000071012bcc10,ResourceInfoContainer::getResourceSize,384,_ZNK4ksys3res21ResourceInfoContainer15getResourceSizeERKN4sead14SafeStringBaseIcEE?
0x00000071012bcd90,sub_71012BCD90,180,_ZNK4ksys3res21ResourceInfoContainer14ResStringEntry7compareERKN4sead14SafeStringBaseIcEE
0x00000071012bce44,sub_71012BCE44,176,_ZN4ksys3res12_GLOBAL__N_114stringLessThanERKN4sead14SafeStringBaseIcEES6_
0x00000071012bcef4,res::ResourceMgrTask::BinderArray::ctor,136,_ZN4ksys3res16ResourceUnitPoolC1Ev

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

@ -1 +1 @@
Subproject commit b19dff3386d866b32f05d92bd1eb7ca93f1a398a
Subproject commit 469724042e81233bba78118548ddd8da5c3d890d

View File

@ -146,11 +146,10 @@ void Cache::eraseUnit(ResourceUnit* unit) {
}
void Cache::removeUnitAndClearCache_(ResourceUnit* unit) {
ResourceMgrTask::ClearCacheArg arg{unit};
unit->mStatusFlags.reset(ResourceUnit::StatusFlag::_20000);
if (unit->isStatusFlag8000Set()) {
ResourceMgrTask::instance()->eraseUnit(unit);
ResourceMgrTask::instance()->clearCache(arg);
ResourceMgrTask::instance()->deregisterUnit(unit);
ResourceMgrTask::instance()->requestClearCache(unit);
}
}

View File

@ -42,8 +42,7 @@ KSYS_CHECK_SIZE_NX150(ControlTask, 0x1f8);
class ControlTaskRequest : public util::TaskRequest {
SEAD_RTTI_OVERRIDE(ControlTaskRequest, util::TaskRequest)
public:
ControlTaskRequest() = default;
ControlTaskRequest(bool has_handle) : TaskRequest(has_handle) {}
explicit ControlTaskRequest(bool has_handle = false) : TaskRequest(has_handle) {}
bool mHasResLoadReq = false;
ResourceUnit* mPackResUnit = nullptr;

View File

@ -80,7 +80,7 @@ bool ResourceInfoContainer::loadResourceSizeTable() {
}
// NON_MATCHING: missing mStringEntries(string_entry_idx).res_size > 0 check
u32 ResourceInfoContainer::getResourceSize(const sead::SafeString& name) {
u32 ResourceInfoContainer::getResourceSize(const sead::SafeString& name) const {
const u32 name_hash = sead::HashCRC32::calcStringHash(name.cstr());
const s32 entry_idx = mEntries.binarySearch({name_hash, 0}, ResEntry::compareT);

View File

@ -14,7 +14,13 @@ public:
virtual ~ResourceInfoContainer();
bool loadResourceSizeTable();
u32 getResourceSize(const sead::SafeString& name);
u32 getResourceSize(const sead::SafeString& name) const;
u32 getResourceSize(const sead::SafeString& prefix, const sead::SafeString& name) const {
sead::FormatFixedSafeString<128> canonical_name{"%s%s", prefix.cstr(), name.cstr()};
return getResourceSize(canonical_name);
}
private:
struct ResEntry {

View File

@ -1,20 +1,39 @@
#include "KingSystem/Resource/resResourceMgrTask.h"
#include <framework/seadHeapPolicies.h>
#include <framework/seadTaskID.h>
#include <resource/seadResourceMgr.h>
#include <resource/seadSZSDecompressor.h>
#include <thread/seadThreadUtil.h>
#include "KingSystem/Resource/resCache.h"
#include "KingSystem/Resource/resCompactedHeap.h"
#include "KingSystem/Resource/resEntryFactory.h"
#include "KingSystem/Resource/resMemoryTask.h"
#include "KingSystem/Resource/resSystem.h"
#include "KingSystem/Resource/resTextureHandleList.h"
#include "KingSystem/Resource/resTextureHandleMgr.h"
#include "KingSystem/System/OverlayArenaSystem.h"
#include "KingSystem/Utils/SafeDelete.h"
#include "KingSystem/Utils/Thread/GameTaskThread.h"
#include "KingSystem/Utils/Thread/TaskMgr.h"
#include "KingSystem/Utils/Thread/TaskQueueBase.h"
#include "KingSystem/Utils/Thread/TaskQueueLock.h"
#include "KingSystem/Utils/Thread/TaskThread.h"
namespace ksys::res {
namespace {
class ClearCachesTaskData : public util::TaskData {
SEAD_RTTI_OVERRIDE(ClearCachesTaskData, util::TaskData)
public:
virtual ~ClearCachesTaskData() = default;
bool _8;
s32 _c;
sead::SafeString mStr;
};
KSYS_CHECK_SIZE_NX150(ClearCachesTaskData, 0x20);
} // namespace
void ResourceMgrTask::setInstance(ResourceMgrTask* task) {
if (!sInstance) {
sInstance = task;
@ -99,6 +118,191 @@ util::TaskThread* ResourceMgrTask::makeResourceLoadingThread(sead::Heap* heap,
sead::MessageQueue::BlockType::Blocking, 0x7fffffff, 0xa000, 32);
}
void ResourceMgrTask::clearAllCaches(OverlayArena* arena) {
mResourceControlThread->getTaskQueue()->waitForLaneToEmpty(u8(LaneId::_5));
mResourceControlThread->getTaskQueue()->waitForLaneToEmpty(u8(LaneId::_4));
mResourceControlThread->getTaskQueue()->waitForLaneToEmpty(u8(LaneId::_3));
MemoryTaskRequest req;
req.mLaneId = u8(LaneId::_9);
req.mHasHandle = true;
req.mSynchronous = false;
req.mThread = mResourceMemoryThread;
req.mDelegate = &mClearAllCachesFn;
req.mName = "ClearAllCaches";
req.mData_8 = false;
req.mData_c = -1;
req.mData_mStr = arena->getHeap()->getName();
util::TaskMgrRequest task_mgr_request;
task_mgr_request.request = &req;
mResourceMemoryTaskMgr->submitRequest(task_mgr_request);
}
bool ResourceMgrTask::isDefragDone() const {
return mTask2->getStatus() == util::Task::Status::PostFinishCallback;
}
f32 ResourceMgrTask::getDefragProgress() const {
auto lock = sead::makeScopedLock(mArenasCS);
if (_4c8 == -1)
return 0;
return f32(_4cc) / f32(_4c8);
}
void ResourceMgrTask::cancelTasks() {
stubbedLogFunction();
stubbedLogFunction();
mMovableMemoryThread->cancelTasks(u8(LaneId::_1));
mMovableMemoryThread->cancelTasks(u8(LaneId::_0));
mMovableMemoryThread->cancelTasks(u8(LaneId::_3));
mMovableMemoryThread->cancelTasks(u8(LaneId::_4));
stubbedLogFunction();
stubbedLogFunction();
mResourceControlThread->cancelTasks(u8(LaneId::_0));
mResourceControlThread->cancelTasks(u8(LaneId::_1));
mResourceControlThread->cancelTasks(u8(LaneId::_2));
stubbedLogFunction();
stubbedLogFunction();
mResourceMemoryThread->cancelTasks(u8(LaneId::_1));
mResourceMemoryThread->cancelTasks(u8(LaneId::_2));
mResourceMemoryThread->cancelTasks(u8(LaneId::_3));
mResourceMemoryThread->cancelTasks(u8(LaneId::_4));
mResourceMemoryThread->cancelTasks(u8(LaneId::_5));
mResourceMemoryThread->cancelTasks(u8(LaneId::_6));
stubbedLogFunction();
stubbedLogFunction();
mResourceLoadingThread->cancelTasks(u8(LaneId::_0));
mResourceLoadingThread->cancelTasks(u8(LaneId::_1));
mResourceLoadingThread->cancelTasks(u8(LaneId::_2));
stubbedLogFunction();
stubbedLogFunction();
}
void ResourceMgrTask::waitForTaskQueuesToEmpty() {
if (mResourceControlThread->isPaused() || mResourceMemoryThread->isPaused() ||
mResourceLoadingThread->isPaused()) {
return;
}
mResourceControlThread->waitForQueueToEmpty();
mResourceMemoryThread->waitForQueueToEmpty();
mResourceLoadingThread->waitForQueueToEmpty();
}
s32 ResourceMgrTask::getNumActiveTasksOnResLoadingThread() const {
return mResourceLoadingThread->getNumActiveTasks();
}
OffsetReadFileDevice* ResourceMgrTask::getOffsetReadFileDevice() const {
return mOffsetReadFileDevice;
}
sead::ArchiveFileDevice* ResourceMgrTask::getArchiveFileDev1() {
return &mArchiveFileDev1;
}
void ResourceMgrTask::controlField9c0d88(bool off) {
if (off) {
_9c0d88.decrement();
static_cast<void>(_9c0d88.load());
} else {
_9c0d88.increment();
}
mFlags.change(Flag::_400, _9c0d88 <= 0);
}
void ResourceMgrTask::setFlag2000Or5000(s32 type) {
if (type != 0) {
mFlags.set(Flag::_1000);
mFlags.set(Flag::_4000);
stubbedLogFunction();
} else {
mFlags.set(Flag::_2000);
}
}
bool ResourceMgrTask::isFlag4Set() const {
return mFlags.isOn(Flag::_4);
}
void ResourceMgrTask::registerUnit(ResourceUnit* unit) {
auto lock = sead::makeScopedLock(mUnitsCS);
mUnits.pushBack(unit);
if (res::returnFalse())
stubbedLogFunction();
}
void ResourceMgrTask::deregisterUnit(ResourceUnit* unit) {
auto lock = sead::makeScopedLock(mUnitsCS);
if (unit->isLinkedToResourceMgr()) {
mUnits.erase(unit);
if (res::returnFalse())
stubbedLogFunction();
}
}
void ResourceMgrTask::deleteUnit(ResourceUnit*& unit, bool sync) {
if (!unit)
return;
const bool immediate = mResourceControlThread->isPaused() || sync;
if (!immediate && res::returnFalse())
stubbedLogFunction();
unit->unloadArchiveRes();
if (immediate) {
mUnitPool.freeForSync(unit);
unit = nullptr;
} else {
mUnitPool.free(unit);
unit = nullptr;
if (res::returnFalse())
stubbedLogFunction();
}
}
void ResourceMgrTask::requestDeleteUnit(ResourceUnit** p_unit) {
if (!p_unit || !*p_unit) {
stubbedLogFunction();
return;
}
if (mResourceControlThread->isPaused()) {
if (res::returnFalse())
stubbedLogFunction();
deleteUnit(*p_unit, false);
} else {
ControlTaskRequest req;
req.mHasHandle = false;
req.mSynchronous = false;
req.mLaneId = u8(LaneId::_5);
req.mThread = mResourceControlThread;
req.mDelegate = &mUnitDeleteFn;
req.mName = "DeleteUnit";
req.mUserData = *p_unit;
(*p_unit)->mTask1.submitRequest(req);
}
*p_unit = nullptr;
}
bool ResourceMgrTask::canUseSdCard() const {
return false;
}
bool ResourceMgrTask::returnFalse() const {
return false;
}
bool ResourceMgrTask::calc_(void*) {
if (mCacheControlFlags.testAndClear(CacheControlFlag::ClearAllCachesRequested)) {
MemoryTaskRequest req;
@ -121,4 +325,286 @@ bool ResourceMgrTask::calc_(void*) {
return true;
}
bool ResourceMgrTask::dropSFromExtensionIfNeeded(const sead::SafeString& path,
sead::BufferedSafeString& new_path, s32 dot_idx,
const sead::SafeString& extension) const {
if (extension == "sbfevfl" || extension == "sbcamanim" || extension == "sbarslist") {
new_path.copyAtWithTerminate(0, path, dot_idx);
new_path.appendWithFormat(".%s", &extension.at(1));
return true;
}
return mExtensions2.binarySearch(&extension) != -1;
}
void ResourceMgrTask::unloadSeadResource(sead::Resource* resource) {
if (res::returnFalse())
stubbedLogFunction();
sead::ResourceMgr::instance()->unload(resource);
stubbedLogFunction();
if (res::returnFalse())
stubbedLogFunction();
}
u32 ResourceMgrTask::getResourceSize(const sead::SafeString& name,
sead::FileDevice* file_device) const {
if (!file_device)
return mResourceInfoContainer.getResourceSize(name);
mFileDevicePrefixesLock.readLock();
for (const auto& entry : mFileDevicePrefixes) {
if (entry.getFileDevice() == file_device) {
const u32 size = mResourceInfoContainer.getResourceSize(entry.getPrefix(), name);
if (size == 0 && entry.getField28())
break;
mFileDevicePrefixesLock.readUnlock();
return size;
}
}
mFileDevicePrefixesLock.readUnlock();
return mResourceInfoContainer.getResourceSize(name);
}
void ResourceMgrTask::registerFileDevicePrefix(FileDevicePrefix& prefix) {
mFileDevicePrefixesLock.writeLock();
mFileDevicePrefixes.pushBack(&prefix);
mFileDevicePrefixesLock.writeUnlock();
}
void ResourceMgrTask::deregisterFileDevicePrefix(FileDevicePrefix& prefix) {
mFileDevicePrefixesLock.writeLock();
mFileDevicePrefixes.erase(&prefix);
mFileDevicePrefixesLock.writeUnlock();
}
void ResourceMgrTask::callStubbedFunctionOnArenas() {
auto lock = sead::makeScopedLock(mArenasCS);
for (OverlayArena& arena : mArenas) {
if (arena.isFlag8Set())
arena.stubbed();
}
}
void ResourceMgrTask::updateResourceArenasFlag8() {
mArenaForResourceS.updateFlag8(false);
mArenaForResourceL.updateFlag8(false);
}
// NON_MATCHING: branching
sead::Heap* ResourceMgrTask::makeHeapForUnit(const MakeHeapArg& arg) {
const auto heap_size = arg.heap_size;
const auto path = arg.path;
OverlayArena* arena = arg.arena;
if (!arena) {
if (heap_size > 0x80000)
arena = &mArenaForResourceL;
else
arena = &mArenaForResourceS;
}
sead::Heap* const heap =
arena->makeDualHeap(heap_size, path, sead::Heap::cHeapDirection_Forward, arg.unit, false);
if (!heap) {
static_cast<void>(arena->isFlag10Set());
*arg.out_arena1 = arena;
return nullptr;
}
if (arg.out_arena2 == nullptr)
return heap;
*arg.out_arena1 = arena;
*arg.out_arena2 = arena;
return heap;
}
ResourceUnit* ResourceMgrTask::clearCachesAndGetUnit(const GetUnitArg& arg) {
auto* unit = mUnitPool.tryAlloc();
if (!unit) {
util::TaskQueueLock lock;
auto* queue = mResourceControlThread->getTaskQueue();
auto it = queue->activeTasksRobustBegin(&lock);
const auto end = queue->activeTasksRobustEnd();
while (it != end && it->getLaneId() >= u8(ResourceMgrTask::LaneId::_5)) {
it->removeFromQueue2();
it->processOnCurrentThreadDirectly(mResourceControlThread);
++it;
}
unit = mUnitPool.tryAlloc();
}
if (!unit) {
ClearCachesTaskData data;
data._8 = true;
data._c = 100;
util::TaskRequest req;
req.mLaneId = u8(LaneId::_8);
req.mHasHandle = true;
req.mSynchronous = true;
req.mThread = mResourceMemoryThread;
req.mDelegate = &mClearCachesFn;
req.mUserData = &data;
req.mName = "ClearCaches";
mTask3->submitRequest(req);
unit = mUnitPool.tryAlloc();
}
if (!unit) {
util::TaskQueueLock lock;
auto* queue = mResourceControlThread->getTaskQueue();
auto it = queue->activeTasksRobustBegin(&lock);
const auto end = queue->activeTasksRobustEnd();
while (it != end && it->getLaneId() >= u8(ResourceMgrTask::LaneId::_5)) {
it->removeFromQueue2();
it->processOnCurrentThreadDirectly(mResourceControlThread);
++it;
}
unit = mUnitPool.tryAlloc();
}
if (!unit->init(*arg.unit_init_arg))
return nullptr;
return unit;
}
void ResourceMgrTask::setActorCreateInitializerThreads(
const SetActorCreateInitializerThreadsArg& arg) {
mFlags.set(Flag::_8);
mActorCreateInitializerThreads = arg.threads;
stubbedLogFunction();
}
void ResourceMgrTask::clearActorCreateInitializerThreads() {
mFlags.reset(Flag::_8);
mActorCreateInitializerThreads = nullptr;
stubbedLogFunction();
}
void ResourceMgrTask::pauseThreads() {
stubbedLogFunction();
mMovableMemoryThread->pauseAndWaitForAck();
mMovableMemoryThread->cancelTasks(3);
mResourceControlThread->pauseAndWaitForAck();
mResourceMemoryThread->pauseAndWaitForAck();
mResourceLoadingThread->pauseAndWaitForAck();
stubbedLogFunction();
}
void ResourceMgrTask::resumeThreads() {
stubbedLogFunction();
mResourceLoadingThread->resume();
mResourceMemoryThread->resume();
mResourceControlThread->resume();
mMovableMemoryThread->resume();
}
sead::SZSDecompressor* ResourceMgrTask::getSzsDecompressor() {
mSzsDecompressorCS.lock();
sead::SZSDecompressor* ptr = nullptr;
OverlayArenaSystem::instance()->getSzsDecompressor(&ptr);
return ptr;
}
void ResourceMgrTask::unlockSzsDecompressorCS() {
mSzsDecompressorCS.unlock();
}
bool ResourceMgrTask::getUncompressedSize(u32* size, const sead::SafeString& path,
sead::FileDevice* device) const {
auto lock = sead::makeScopedLock(mSzsDecompressorCS);
if (!device)
device = mSeadMainFileDevice;
sead::FileHandle handle;
if (!device->tryOpen(&handle, path, sead::FileDevice::cFileOpenFlag_ReadOnly)) {
stubbedLogFunction();
return false;
}
u32 read_size = 0;
handle.tryRead(&read_size, mOffsetReadBuf, 0x10);
*size = sead::Mathu::roundUpPow2(sead::SZSDecompressor::getDecompSize(mOffsetReadBuf), 32);
return true;
}
// NON_MATCHING: reordering
void ResourceMgrTask::setCompactionStopped(bool stopped) {
u32 old_counter;
if (stopped)
old_counter = mCompactionCounter.decrement();
else
old_counter = mCompactionCounter.increment();
stubbedLogFunction();
if (mCompactionCounter == 0 || old_counter == 0)
stubbedLogFunction();
}
bool ResourceMgrTask::isCompactionStopped() const {
return mCompactionCounter == 0;
}
bool ResourceMgrTask::returnTrue1() {
return true;
}
void ResourceMgrTask::clearCacheWithFileExtension(const sead::SafeString& extension) {
stubbedLogFunction();
const s32 idx = getCacheIdx(extension);
stubbedLogFunction();
mCaches[idx]->eraseUnits();
}
void ResourceMgrTask::clearAllCachesSynchronously(OverlayArena* arena) {
mResourceControlThread->getTaskQueue()->waitForLaneToEmpty(u8(LaneId::_5));
mResourceControlThread->getTaskQueue()->waitForLaneToEmpty(u8(LaneId::_4));
mResourceControlThread->getTaskQueue()->waitForLaneToEmpty(u8(LaneId::_3));
MemoryTaskRequest req;
req.mLaneId = u8(LaneId::_9);
req.mHasHandle = true;
req.mSynchronous = true;
req.mThread = mResourceMemoryThread;
req.mDelegate = &mClearAllCachesFn;
req.mName = "ClearAllCaches";
req.mData_8 = false;
req.mData_c = -1;
req.mData_mStr = arena->getHeap()->getName();
util::TaskMgrRequest task_mgr_request;
task_mgr_request.request = &req;
mResourceMemoryTaskMgr->submitRequest(task_mgr_request);
}
bool ResourceMgrTask::returnTrue() {
return true;
}
void ResourceMgrTask::removeOverlayArena(OverlayArena* arena) {
mTask.removeFromQueue();
auto lock = sead::makeScopedLock(mArenasCS);
mArenaIdx = 0;
if (mArenas.isNodeLinked(arena)) {
mArenas.erase(arena);
stubbedLogFunction();
}
}
} // namespace ksys::res

View File

@ -10,6 +10,8 @@
#include <framework/seadCalculateTask.h>
#include <hostio/seadHostIONode.h>
#include <prim/seadDelegate.h>
#include <prim/seadSafeString.h>
#include <prim/seadStringBuilder.h>
#include <prim/seadTypedBitFlag.h>
#include <thread/seadAtomic.h>
#include <thread/seadCriticalSection.h>
@ -25,7 +27,9 @@
namespace sead {
class Heap;
}
class Resource;
class SZSDecompressor;
} // namespace sead
namespace ksys {
class OverlayArena;
@ -52,26 +56,39 @@ class FileDevicePrefix {
public:
FileDevicePrefix() = default;
sead::FileDevice* getFileDevice() { return mFileDevice; }
sead::FileDevice* getFileDevice() const { return mFileDevice; }
void setFileDevice(sead::FileDevice* device) { mFileDevice = device; }
const sead::SafeString& getPrefix() { return mPrefix; }
const sead::SafeString& getPrefix() const { return mPrefix; }
void setPrefix(const sead::SafeString& prefix) { mPrefix = prefix; }
bool getField28() const { return _28; }
void setField28(bool value) { _28 = value; }
static constexpr size_t getListNodeOffset() { return offsetof(FileDevicePrefix, mListNode); }
private:
sead::ListNode mListNode;
sead::FileDevice* mFileDevice = nullptr;
sead::SafeString mPrefix;
bool _28 = false;
};
KSYS_CHECK_SIZE_NX150(FileDevicePrefix, 0x28);
KSYS_CHECK_SIZE_NX150(FileDevicePrefix, 0x30);
// FIXME: very, very incomplete.
// FIXME: very incomplete.
class ResourceMgrTask : public sead::CalculateTask, public sead::hostio::Node {
SEAD_RTTI_OVERRIDE(ResourceMgrTask, sead::CalculateTask)
public:
enum class LaneId {
_0 = 0,
_1 = 1,
_2 = 2,
_3 = 3,
_4 = 4,
_5 = 5,
_6 = 6,
_7 = 7,
_8 = 8,
_9 = 9,
_10 = 10,
};
@ -91,26 +108,141 @@ public:
void prepare() override;
void insertOverlayArena(OverlayArena* arena);
OverlayArena* getSomeArena() const;
util::TaskThread* makeResourceLoadingThread(sead::Heap* heap, bool use_game_task_thread);
void clearAllCaches(OverlayArena* arena);
OverlayArena* getTexHandleMgrArena() const;
void requestDefragAllMemoryMgr();
bool isDefragDone() const;
f32 getDefragProgress() const;
s32 getCacheIdx(const sead::SafeString& path) const;
void cancelTasks();
void waitForTaskQueuesToEmpty();
s32 getNumActiveTasksOnResLoadingThread() const;
OffsetReadFileDevice* getOffsetReadFileDevice() const;
sead::ArchiveFileDevice* getArchiveFileDev1();
void controlField9c0d88(bool off);
void setFlag2000Or5000(s32 type);
void copyLoadRequest(ILoadRequest* request, const sead::SafeString& path,
const ILoadRequest& source_request);
EntryFactoryBase* getFactoryForPath(const sead::SafeString& path) const;
bool isFlag4Set() const;
s32 requestLoad(Handle* handle, const sead::SafeString& path, const ILoadRequest& request);
void addSExtensionPrefix(sead::StringBuilder& builder) const;
s32 requestLoadForSync(Handle* handle, const sead::SafeString& path,
const ILoadRequest& request);
s32 requestUnload(Handle* handle, const sead::SafeString& path, const ILoadRequest& request);
void registerUnit(ResourceUnit* unit);
void deregisterUnit(ResourceUnit* unit);
void requestClearCache(ResourceUnit*& unit, void* x = nullptr);
void requestClearCacheForSync(ResourceUnit*& unit, bool clear_immediately,
bool delete_immediately);
void deleteUnit(ResourceUnit*& unit, bool sync);
void requestDeleteUnit(ResourceUnit** p_unit);
struct DirectLoadArg {
LoadRequest req;
sead::Heap* heap;
};
sead::DirectResource* load(const DirectLoadArg& arg);
bool canUseSdCard() const;
bool returnFalse() const;
bool dropSFromExtensionIfNeeded(const sead::SafeString& path,
sead::BufferedSafeString& new_path, s32 dot_idx,
const sead::SafeString& extension) const;
void unloadSeadResource(sead::Resource* resource);
u32 getResourceSize(const sead::SafeString& name, sead::FileDevice* file_device) const;
void registerFileDevicePrefix(FileDevicePrefix& prefix);
void deregisterFileDevicePrefix(FileDevicePrefix& prefix);
void callStubbedFunctionOnArenas();
void updateResourceArenasFlag8();
struct MakeHeapArg {
bool _0 = false;
u32 heap_size = 0;
ResourceUnit* unit = nullptr;
sead::SafeString path;
OverlayArena* arena = nullptr;
OverlayArena** out_arena1 = nullptr;
OverlayArena** out_arena2 = nullptr;
};
KSYS_CHECK_SIZE_NX150(MakeHeapArg, 0x38);
sead::Heap* makeHeapForUnit(const MakeHeapArg& arg);
struct GetUnitArg {
const ResourceUnit::InitArg* unit_init_arg;
OverlayArena* arena;
};
ResourceUnit* clearCachesAndGetUnit(const GetUnitArg& arg);
void eraseUnit(ResourceUnit* unit);
struct ClearCacheArg {
ResourceUnit* unit;
struct SetActorCreateInitializerThreadsArg {
sead::PtrArray<util::TaskThread>* threads;
};
void clearCache(ClearCacheArg& arg, void* x = nullptr);
void setActorCreateInitializerThreads(const SetActorCreateInitializerThreadsArg& arg);
void clearActorCreateInitializerThreads();
bool dropSFromExtensionIfNeeded(const sead::SafeString& path,
sead::BufferedSafeString& new_path, s32 dot_idx,
const sead::SafeString& extension);
void pauseThreads();
void resumeThreads();
sead::SZSDecompressor* getSzsDecompressor();
void unlockSzsDecompressorCS();
bool getUncompressedSize(u32* size, const sead::SafeString& path,
sead::FileDevice* device) const;
void setCompactionStopped(bool stopped);
bool isCompactionStopped() const;
bool returnTrue1();
void clearCacheWithFileExtension(const sead::SafeString& extension);
void clearAllCachesSynchronously(OverlayArena* arena);
bool returnTrue();
struct ResourceSizeInfo {
bool is_archive_file_dev2;
u32 buffer_size;
u32 alloc_size;
sead::FileDevice* file_device;
};
KSYS_CHECK_SIZE_NX150(ResourceSizeInfo, 0x18);
struct GetResourceSizeInfoArg {
bool flag1;
bool flag4_try_decomp;
bool flag2;
u32 alloc_size;
sead::ArchiveRes* archive_res;
sead::FileDevice* file_device;
EntryFactoryBase* factory;
u32 load_data_alignment;
sead::SafeString str; // TODO: rename
sead::SafeString path;
};
KSYS_CHECK_SIZE_NX150(GetResourceSizeInfoArg, 0x48);
void getResourceSizeInfo(ResourceSizeInfo* info, const GetResourceSizeInfoArg& arg);
void removeOverlayArena(OverlayArena* arena);
util::TaskThread* getResourceLoadingThread() const { return mResourceLoadingThread; }
util::TaskThread* getResourceControlThread() const { return mResourceControlThread; }
@ -122,7 +254,14 @@ public:
private:
enum class Flag {
_1 = 1,
_2 = 2,
_4 = 4,
_8 = 8,
_400 = 0x400,
_1000 = 0x1000,
_2000 = 0x2000,
_4000 = 0x4000,
};
enum class CacheControlFlag : u8 {
@ -168,10 +307,10 @@ private:
EntryFactoryBase* mEntryFactoryBase = nullptr;
EntryFactoryBase* mDefaultEntryFactory = nullptr;
sead::Buffer<Cache> mCaches;
sead::Buffer<Cache*> mCaches;
sead::FixedObjArray<s32, 4> mThreadIds;
u8* mOffsetReadBuf = nullptr;
sead::CriticalSection mSzsDecompressorCS;
mutable sead::CriticalSection mSzsDecompressorCS;
sead::CriticalSection mFactoryCS;
ResourceUnitDelegatePair mUnitInitLoadFn;
@ -197,10 +336,10 @@ private:
ResourceUnitDelegate mUnitDeleteFn;
s32 _4c8 = -1;
u32 _4cc = 0;
s32 _4cc = 0;
ResourceUnitPool mUnitPool;
sead::CriticalSection mCritSection;
sead::CriticalSection mUnitsCS;
sead::OffsetList<ResourceUnit> mUnits;
sead::OffsetList<bool> mSomeList; // TODO: fix the type and rename
@ -217,7 +356,7 @@ private:
sead::ObjArray<sead::SafeString> mExtensions2; // TODO: rename
sead::OffsetList<OverlayArena> mArenas;
sead::CriticalSection mArenasCS;
mutable sead::CriticalSection mArenasCS;
OverlayArena mArenaForResourceS;
OverlayArena mArenaForResourceL;
@ -225,7 +364,7 @@ private:
ResourceInfoContainer mResourceInfoContainer;
sead::OffsetList<FileDevicePrefix> mFileDevicePrefixes;
sead::ReadWriteLock mFileDevicePrefixesLock;
mutable sead::ReadWriteLock mFileDevicePrefixesLock;
TextureHandleMgr* mTexHandleMgr = nullptr;
TextureHandleList* mTexHandleList = nullptr;
@ -237,16 +376,16 @@ private:
u8* mCompactedHeapMip0Buffer = nullptr;
CompactedHeap* mCompactedHeapMip0 = nullptr;
u8* mCompactedHeapMainBuffer2 = nullptr;
sead::Atomic<u32> mCompactionStopped = 0;
sead::Atomic<u32> mCompactionCounter = 0;
sead::Atomic<u32> _9c0d3c = 0;
sead::Atomic<u32> _9c0d40 = 0;
sead::AnyDelegate2<sead::Thread*, sead::MessageQueue::Element> mCompactionThreadFn;
sead::DelegateThread* mCompactionThread = nullptr;
Counter mCounter;
u32 _9c0d88 = 1;
sead::Atomic<s32> _9c0d88 = 1;
u32 _9c0d8c = 0;
u32 _9c0d90 = 0;
u32 mArenaIdx = 0;
u32 _9c0d94;
u8 _9c0d98 = 1;
size_t _9c0da0 = 500;

View File

@ -10,8 +10,12 @@ bool returnFalse() {
return false;
}
bool returnFalse2() {
bool returnFalse2(const sead::SafeString&) {
return false;
}
s32 getDefaultAlignment() {
return 8;
}
} // namespace ksys::res

View File

@ -16,4 +16,6 @@ bool returnFalse();
// TODO: figure out what this is used for. Stubbed log function?
bool returnFalse2(const sead::SafeString&);
s32 getDefaultAlignment();
} // namespace ksys::res

View File

@ -145,8 +145,8 @@ public:
/// Destroys the underlying resource and reallocates it for defragmentation purposes.
void reallocate();
u32 determineFileBufferSize();
u32 determineFileBufferSize(const sead::SafeString& path, bool flag4, bool flag1, bool flag2);
u32 determineHeapSize();
u32 determineHeapSize(const sead::SafeString& path, bool flag4, bool flag1, bool flag2);
void detachFromHandle_(Handle* handle);
@ -165,6 +165,7 @@ public:
private:
friend class Cache;
friend class Handle;
friend class ResourceMgrTask;
enum class CacheFlag : u8 {
IsLinkedToCache = 0x1,

View File

@ -3,12 +3,13 @@
#include "KingSystem/Resource/resResourceMgrTask.h"
#include "KingSystem/Resource/resSystem.h"
#include "KingSystem/Resource/resUnit.h"
#include "KingSystem/Utils/HeapUtil.h"
namespace ksys {
OverlayArena::OverlayArena() {
mUnits.initOffset(res::ResourceUnit::getArenaUnitListNodeOffset());
mOffsetList2.initOffset(res::ResourceUnit::getArenaUnitListNode2Offset());
mUnits2.initOffset(res::ResourceUnit::getArenaUnitListNode2Offset());
}
OverlayArena::~OverlayArena() {
@ -59,4 +60,110 @@ bool OverlayArena::init(const OverlayArena::InitArg& arg) {
return true;
}
void OverlayArena::stubbed() {}
void OverlayArena::updateFlag8(bool on) {
if (on != mFlags.isOn(Flag::_8) && mHeap)
mFlags.change(Flag::_8, on);
}
void OverlayArena::clearUnits() {
if (!mHeap)
return;
res::stubbedLogFunction();
auto lock = sead::makeScopedLock(mCS);
for (auto it = mUnits.robustBegin(), end = mUnits.robustEnd(); it != end; ++it) {
res::ResourceUnit* unit = std::addressof(*it);
res::stubbedLogFunction();
res::ResourceMgrTask::instance()->deregisterUnit(unit);
res::ResourceMgrTask::instance()->requestClearCacheForSync(unit, true, false);
}
res::stubbedLogFunction();
}
bool OverlayArena::isFlag1Set() const {
return mFlags.isOn(Flag::_1);
}
bool OverlayArena::hasNoUnits() const {
return mUnits.isEmpty();
}
s32 OverlayArena::getNumUnits() const {
return mUnits.size();
}
bool OverlayArena::isFlag10Set() const {
return mFlags.isOn(Flag::_10);
}
bool OverlayArena::isFlag8Set() const {
return mFlags.isOn(Flag::_8);
}
bool OverlayArena::checkIsOom() const {
if (!mHeap)
return false;
const f32 used_size = mUsage1 + mUsage2;
const size_t heap_size = mHeap->getSize();
const f32 free_percentage =
100.0f *
std::max<f32>(1.0 - used_size / (heap_size - sead::ExpHeap::getManagementAreaSize(8)), 0);
if (free_percentage < mMinFreePercentage) {
if (res::returnFalse())
res::stubbedLogFunction();
setBloodyMoonReasonForOom_();
return true;
}
return false;
}
// FIXME: figure out what sead function this is
bool seadCheckPointer(void* ptr);
// NON_MATCHING: branching
util::DualHeap* OverlayArena::makeDualHeap(u32 size, const sead::SafeString& name,
sead::Heap::HeapDirection direction,
res::ResourceUnit* unit, bool) {
if (!mHeap)
return nullptr;
const auto alignment = res::getDefaultAlignment();
const auto lock = sead::makeScopedLock(mCS);
auto* heap = util::DualHeap::tryCreate(size, name, mHeap, mHeap2, alignment, direction, false);
if (!heap) {
if (res::returnFalse())
res::stubbedLogFunction();
if (!x_1(size))
return nullptr;
heap = util::DualHeap::tryCreate(size, name, mHeap, mHeap2, alignment, direction, false);
if (!heap)
return nullptr;
}
if (unit && !seadCheckPointer(unit)) {
mUnits.pushBack(unit);
mFlags.set(Flag::_2);
}
mFlags.set(Flag::_4);
return heap;
}
void OverlayArena::addSize(s32 size) {
mSize += size;
}
void OverlayArena::addSize2(s32 size) {
mUsage1 += size;
}
} // namespace ksys

View File

@ -3,22 +3,22 @@
#include <basis/seadTypes.h>
#include <container/seadListImpl.h>
#include <container/seadOffsetList.h>
#include <heap/seadExpHeap.h>
#include <heap/seadHeap.h>
#include <prim/seadSafeString.h>
#include <prim/seadTypedBitFlag.h>
#include <thread/seadCriticalSection.h>
#include "KingSystem/System/StringBoard.h"
#include "KingSystem/Utils/Types.h"
namespace sead {
class ExpHeap;
class Heap;
} // namespace sead
namespace ksys {
namespace res {
class ResourceUnit;
}
namespace util {
class DualHeap;
}
class OverlayArena {
public:
@ -43,11 +43,33 @@ public:
virtual ~OverlayArena();
bool init(const InitArg& arg);
void stubbed();
void updateFlag8(bool on);
void clearUnits();
bool isFlag1Set() const;
bool hasNoUnits() const;
s32 getNumUnits() const;
void destroy();
bool isFlag10Set() const;
bool isFlag8Set() const;
/// Checks whether this arena is running out of memory.
/// This will also update the panic blood moon reason for the ProductReporter if needed.
/// @return whether the arena is running OOM.
bool checkIsOom() const;
util::DualHeap* makeDualHeap(u32 size, const sead::SafeString& name,
sead::Heap::HeapDirection direction, res::ResourceUnit* unit,
bool x);
void addSize(s32 size);
void addSize2(s32 size);
sead::Heap* getHeap() const { return mHeap; }
sead::Heap* getHeap2() const { return mHeap2; }
static constexpr size_t getListNodeOffset() { return offsetof(OverlayArena, mListNode); }
private:
@ -62,6 +84,10 @@ private:
_20 = 0x20,
};
void setBloodyMoonReasonForOom_() const;
bool x_1(s32 size);
sead::ListNode mListNode;
sead::TypedBitFlag<Flag> mFlags = [] {
decltype(mFlags) flags;
@ -73,12 +99,12 @@ private:
f32 mMinFreePercentage = 0.0;
sead::Heap* mHeap2 = nullptr;
sead::OffsetList<res::ResourceUnit> mUnits;
sead::OffsetList<void*> mOffsetList2; // FIXME: type
sead::OffsetList<res::ResourceUnit> mUnits2; // TODO: rename
sead::CriticalSection mCS;
void* mUsage2 = nullptr;
size_t mUsage2 = 0;
void* _b0 = nullptr;
u32 _b8 = 0;
u32 mUsage1 = 0;
s32 mSize = 0;
s32 mUsage1 = 0;
u32 mHeapFreeSize = 0;
u32 _c4 = 0;
u32 _c8 = 0;

View File

@ -319,9 +319,9 @@ void OverlayArenaSystem::createStubbed() {}
void OverlayArenaSystem::createMovieHeap() {
res::stubbedLogFunction();
mMovieHeap = sead::ExpHeap::tryCreate(0x8c00000, "MovieHeap",
res::ResourceMgrTask::instance()->getSomeArena()->mHeap,
sizeof(void*), sead::Heap::cHeapDirection_Forward, false);
mMovieHeap = sead::ExpHeap::tryCreate(
0x8c00000, "MovieHeap", res::ResourceMgrTask::instance()->getTexHandleMgrArena()->mHeap,
sizeof(void*), sead::Heap::cHeapDirection_Forward, false);
res::stubbedLogFunction();
}