/*** Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: AuProcessSectionAllocations.cpp Date: 2022-09-30 Author: Reece ***/ #include #include "AuProcessSectionAllocations.hpp" namespace Aurora::Process { void ProcessSectionAllocations::ReleaseAddress(AuUInt uOffset) { AU_LOCK_GUARD(this->spinlock); AuTryRemoveByTupleN<0>(this->allocations, uOffset); } bool ProcessSectionAllocations::GetAddress(AuUInt uOffset, AuUInt uLength, AuUInt &uAddressOut, bool &bCompleteBlock) { AU_LOCK_GUARD(this->spinlock); bool bFound {}; AuUInt uFoundAddress {}; auto itr = this->allocations.begin(); AuUInt uEndOfLastAllocation {}; bCompleteBlock = false; while (itr != this->allocations.end()) { auto uBaseAddress = itr->first; auto uLengthAddress = itr->second; itr++; auto uDelta = uBaseAddress - uEndOfLastAllocation; if (uDelta && uDelta >= uLength) { if (uOffset == -1) { uFoundAddress = uEndOfLastAllocation; bCompleteBlock = uDelta == uLength; bFound = true; break; } if ((uEndOfLastAllocation <= uOffset) && (uOffset + uLength) <= uBaseAddress) { uFoundAddress = uEndOfLastAllocation; bCompleteBlock = uDelta == uLength; bFound = true; break; } } uEndOfLastAllocation = uBaseAddress + uLengthAddress; } if (!bFound) { auto uDelta = this->uMaxLength - uEndOfLastAllocation; if (uDelta && uDelta >= uLength) { uFoundAddress = uEndOfLastAllocation; bCompleteBlock = uDelta == uLength; } else { return false; } } if ((uOffset != -1) && (uFoundAddress != uOffset)) { return false; } #if 1 // ordered insert { auto itr = this->allocations.begin(); while (true) { if ((itr == this->allocations.end()) || ((itr->first) > uOffset)) { this->allocations.insert(itr, AuMakePair(uFoundAddress, uLength)); break; } itr++; } } #else if (!AuTryInsert(this->allocations, AuMakePair(uFoundAddress, uLength))) { SysPushErrorMemory(); return false; } #endif uAddressOut = uFoundAddress; return true; } bool ProcessSectionAllocations::IsAddressValid(AuUInt uOffset) { if (AuUInt(-1) == uOffset) { return true; } AU_LOCK_GUARD(this->spinlock); for (const auto & [uCmpOffset, uCmpLength] : this->allocations) { if ((uOffset >= uCmpOffset) && (uOffset <= (uCmpOffset + uCmpOffset))) { return true; } } return false; } }