AuroraRuntime/Source/Process/ProcessSectionAllocations.cpp

129 lines
3.3 KiB
C++
Raw Normal View History

/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: ProcessSectionAllocations.cpp
Date: 2022-09-30
Author: Reece
***/
#include <Source/RuntimeInternal.hpp>
#include "ProcessSectionAllocations.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;
}
}