From 81feab300b56913c624e72e8c348df93da1cdcf4 Mon Sep 17 00:00:00 2001 From: Pistonight Date: Tue, 13 May 2025 11:25:39 -0700 Subject: merge BaseProcHandle and BaseProcUnit TU --- src/KingSystem/ActorSystem/actBaseProcHandle.cpp | 165 ++++++++++++++++++++--- 1 file changed, 145 insertions(+), 20 deletions(-) (limited to 'src/KingSystem/ActorSystem/actBaseProcHandle.cpp') diff --git a/src/KingSystem/ActorSystem/actBaseProcHandle.cpp b/src/KingSystem/ActorSystem/actBaseProcHandle.cpp index 95cfa803..bdde1c62 100644 --- a/src/KingSystem/ActorSystem/actBaseProcHandle.cpp +++ b/src/KingSystem/ActorSystem/actBaseProcHandle.cpp @@ -2,19 +2,15 @@ #include #include "KingSystem/ActorSystem/actActorLinkConstDataAccess.h" #include "KingSystem/ActorSystem/actBaseProc.h" -#include "KingSystem/ActorSystem/actBaseProcUnit.h" -#include "KingSystem/Utils/InitTimeInfo.h" +#include "KingSystem/Utils/Debug.h" namespace ksys::act { -static util::InitTimeInfo sInfo; +BaseProcUnitPool gUnitPool{}; +BaseProcHandle gDummyProcHandle; BaseProcHandle::BaseProcHandle() = default; -BaseProcHandle::~BaseProcHandle() { - deleteProc(); -} - bool BaseProcHandle::isProcReady() const { return mUnit && mUnit->isReady(); } @@ -139,29 +135,158 @@ bool BaseProcHandle::allocUnit() { if (mUnit) return false; - int idx = gUnitPool.idx; - for (int i = 0; i < gUnitPool.units.size(); ++idx, ++i) { - idx = (idx == gUnitPool.units.size()) ? 0 : idx; - auto* unit = gUnitPool.get(idx); + mUnit = gUnitPool.alloc(this); + if (!mUnit) + return false; + + mUnit->setInitializingStatus(); + return true; +} + +BaseProcUnit* BaseProcUnitPool::alloc(BaseProcHandle* handle) { + int idx = next; + for (int i = 0; i < units.array.size(); ++idx, ++i) { + idx = (idx == units.array.size()) ? 0 : idx; + auto* unit = &units.array[idx]; if (!unit->getCreateTask().canSubmitRequest()) continue; if (unit->getProc() != nullptr) continue; - if (!unit->compareExchangeHandle(nullptr, this)) + if (!unit->compareExchangeHandle(nullptr, handle)) continue; - gUnitPool.idx = idx + 1; - mUnit = unit; - if (!mUnit) - return false; + next = idx + 1; + return unit; + } + return nullptr; +} - mUnit->setInitializingStatus(); - return true; +BaseProcUnit::~BaseProcUnit() { + deleteProc(0, nullptr); +} + +bool BaseProcUnit::deleteProc([[maybe_unused]] u32 x, BaseProcHandle* handle) { +#ifdef MATCHING_HACK_NX_CLANG + // Ensure x is not optimized out. + __builtin_assume(x); +#endif + + ActorLinkConstDataAccess accessor; + + { + const auto lock = sead::makeScopedLock(mCS); + BaseProcHandle* current_handle = mHandle; + if (current_handle == handle) { + if (mProc) + accessor.acquire(mProc); + + if (mStatus == Status::Initializing || mProc) { + mHandle.compareExchange(handle, &gDummyProcHandle); + } else { + mStatus = Status::Unused; + mHandle = nullptr; + } + } else { + sead::FixedSafeString<256> message; + message.format("BaseProcUnit:(%p, %p), 呼び出し(%p)", this, current_handle, handle); + util::PrintDebug(message); + } } - mUnit = nullptr; - return false; + if (accessor.hasProc()) + accessor.mProc->deleteLater(BaseProc::DeleteReason::_2); + + return true; +} + +bool BaseProcUnit::setProc(BaseProc* proc) { + static constexpr const char* sStateNames[] = {"Init", "Calc", "Sleep", "Delete"}; + + auto lock = sead::makeScopedLock(mCS); + + if (mProc) + mProc = nullptr; + + if (isParentHandleDefault()) + return false; + + const auto print_info = [&] { + sead::FixedSafeString<64> message; + if (proc) { + message.format("%s, %d, %d, %s, ( %p:%p )", proc->getName().cstr(), u32(mStatus.load()), + proc->isInitialized(), sStateNames[u8(proc->getState())], this, + mHandle.load()); + } else { + message.format("なし, %d, ?, ?, ( %p:%p )", u32(mStatus.load()), this, mHandle.load()); + } + util::PrintDebug(message); + }; + + if (!mHandle) { + print_info(); + return false; + } + + if (mStatus != Status::Initializing) + print_info(); + + mProc = proc; + mStatus = Status::Ready; + return true; +} + +void BaseProcUnit::reset() { + auto* handle = getHandle(); + if (handle != &gDummyProcHandle) { + sead::FixedSafeString<256> message; + message.format("BaseProcUnit:%p, %p", this, handle); + util::PrintDebug(message); + } + mProc = nullptr; + mStatus = Status::Unused; + mHandle = nullptr; +} + +void BaseProcUnit::cleanUp(BaseProc* proc, bool is_cancellation) { + const auto lock = sead::makeScopedLock(mCS); + + mProc = nullptr; + + const auto print_info = [&] { + sead::FixedSafeString<64> message; + message.format("%d, ( %p:%p )", u32(mStatus.load()), this, mHandle.load()); + util::PrintDebug(message); + }; + + if (isParentHandleDefault()) { + reset(); + } else if (!mHandle) { + print_info(); + } else { + const auto status = mStatus.load(); + if (status == Status::Unused || (status > Status::NoProc && status != Status::Cancelled)) + print_info(); + mStatus = is_cancellation ? Status::Cancelled : Status::NoProc; + } +} + +void BaseProcUnit::unlinkProc(BaseProc* proc) { + const auto lock = sead::makeScopedLock(mCS); + + if (mProc != proc && mProc != nullptr) { + sead::FixedSafeString<256> message; + message.format("BaseProcUnit:(%p:%p), BaseProc:(%s:%p), 残りBaseProc(%s:%p)", this, + mHandle.load(), proc->getName().cstr(), proc, mProc->getName().cstr(), + mProc); + util::PrintDebug(message); + } + + reset(); +} + +bool BaseProcUnit::isParentHandleDefault() const { + return mHandle == &gDummyProcHandle; } } // namespace ksys::act -- cgit v1.2.3