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