Common: Clean up ScopedAlloc

This commit is contained in:
TellowKrinkle 2021-11-13 19:21:17 -06:00 committed by tellowkrinkle
parent a4b8c33cf3
commit 8b086a3898
8 changed files with 53 additions and 146 deletions

View File

@ -18,8 +18,8 @@
#if !defined(_WIN32) #if !defined(_WIN32)
#include "common/AlignedMalloc.h"
#include "common/Assertions.h" #include "common/Assertions.h"
#include "common/ScopedAlloc.h"
void* __fastcall _aligned_malloc(size_t size, size_t align) void* __fastcall _aligned_malloc(size_t size, size_t align)
{ {

View File

@ -80,50 +80,57 @@ extern Fnptr_OutOfMemory pxDoOutOfMemory;
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// BaseScopedAlloc // AlignedBuffer
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// Base class that allows various ScopedMalloc types to be passed to functions that act // A simple container class for an aligned allocation. By default, no bounds checking is
// on them. // performed, and there is no option for enabling bounds checking. If bounds checking and
// other features are needed, use the more robust SafeArray<> instead.
// //
// Rationale: This class and the derived varieties are provided as a simple autonomous self- template <typename T, uint align>
// destructing container for malloc. The entire class is almost completely dependency free, class AlignedBuffer
// and thus can be included everywhere and anywhere without dependency hassles.
//
template <typename T>
class BaseScopedAlloc
{ {
protected: static_assert(std::is_pod<T>::value, "Must use a POD type");
T* m_buffer;
uint m_size; struct Deleter
{
void operator()(T* ptr)
{
_aligned_free(ptr);
}
};
std::unique_ptr<T[], Deleter> m_buffer;
std::size_t m_size;
public: public:
BaseScopedAlloc() AlignedBuffer(size_t size = 0)
{ {
m_buffer = NULL; Alloc(size);
m_size = 0;
} }
virtual ~BaseScopedAlloc()
{
//pxAssert(m_buffer==NULL);
}
public:
size_t GetSize() const { return m_size; } size_t GetSize() const { return m_size; }
size_t GetLength() const { return m_size; } size_t GetLength() const { return m_size; }
// Allocates the object to the specified size. If an existing allocation is in void Alloc(size_t newsize)
// place, it is freed and replaced with the new allocation, and all data is lost. {
// Parameter: m_size = newsize;
// newSize - size of the new allocation, in elements (not bytes!). If the specified m_buffer.reset();
// size is 0, the the allocation is freed, same as calling Free(). if (!m_size)
virtual void Alloc(size_t newsize) = 0; return;
// Re-sizes the allocation to the requested size, without any data loss. m_buffer.reset(reinterpret_cast<T*>(_aligned_malloc(this->m_size * sizeof(T), align)));
// Parameter: if (!m_buffer)
// newSize - size of the new allocation, in elements (not bytes!). If the specified throw std::bad_alloc();
// size is 0, the the allocation is freed, same as calling Free(). }
virtual void Resize(size_t newsize) = 0;
void Resize(size_t newsize)
{
m_buffer.reset(reinterpret_cast<T*>(pcsx2_aligned_realloc(m_buffer.release(), newsize * sizeof(T), align, m_size * sizeof(T))));
m_size = newsize;
if (!m_buffer)
throw std::bad_alloc();
}
void Free() void Free()
{ {
@ -162,103 +169,3 @@ public:
return m_buffer[idx]; return m_buffer[idx];
} }
}; };
// --------------------------------------------------------------------------------------
// ScopedAlloc
// --------------------------------------------------------------------------------------
// A simple container class for a standard malloc allocation. By default, no bounds checking
// is performed, and there is no option for enabling bounds checking. If bounds checking and
// other features are needed, use the more robust SafeArray<> instead.
//
// See docs for BaseScopedAlloc for details and rationale.
//
template <typename T>
class ScopedAlloc : public BaseScopedAlloc<T>
{
typedef BaseScopedAlloc<T> _parent;
public:
ScopedAlloc(size_t size = 0)
: _parent()
{
Alloc(size);
}
virtual ~ScopedAlloc()
{
safe_free(this->m_buffer);
}
virtual void Alloc(size_t newsize)
{
safe_free(this->m_buffer);
this->m_size = newsize;
if (!this->m_size)
return;
this->m_buffer = (T*)malloc(this->m_size * sizeof(T));
if (!this->m_buffer)
throw Exception::OutOfMemory(L"ScopedAlloc");
}
virtual void Resize(size_t newsize)
{
this->m_size = newsize;
this->m_buffer = (T*)realloc(this->m_buffer, this->m_size * sizeof(T));
if (!this->m_buffer)
throw Exception::OutOfMemory(L"ScopedAlloc::Resize");
}
using _parent::operator[];
};
// --------------------------------------------------------------------------------------
// ScopedAlignedAlloc
// --------------------------------------------------------------------------------------
// A simple container class for an aligned allocation. By default, no bounds checking is
// performed, and there is no option for enabling bounds checking. If bounds checking and
// other features are needed, use the more robust SafeArray<> instead.
//
// See docs for BaseScopedAlloc for details and rationale.
//
template <typename T, uint align>
class ScopedAlignedAlloc : public BaseScopedAlloc<T>
{
typedef BaseScopedAlloc<T> _parent;
public:
ScopedAlignedAlloc(size_t size = 0)
: _parent()
{
Alloc(size);
}
virtual ~ScopedAlignedAlloc()
{
safe_aligned_free(this->m_buffer);
}
virtual void Alloc(size_t newsize)
{
safe_aligned_free(this->m_buffer);
this->m_size = newsize;
if (!this->m_size)
return;
this->m_buffer = (T*)_aligned_malloc(this->m_size * sizeof(T), align);
if (!this->m_buffer)
throw Exception::OutOfMemory(L"ScopedAlignedAlloc");
}
virtual void Resize(size_t newsize)
{
this->m_buffer = (T*)pcsx2_aligned_realloc(this->m_buffer, newsize * sizeof(T), align, this->m_size * sizeof(T));
this->m_size = newsize;
if (!this->m_buffer)
throw Exception::OutOfMemory(L"ScopedAlignedAlloc::Resize");
}
using _parent::operator[];
};

View File

@ -61,6 +61,7 @@ target_sources(common PRIVATE
# x86emitter headers # x86emitter headers
target_sources(common PRIVATE target_sources(common PRIVATE
Align.h Align.h
AlignedMalloc.h
Assertions.h Assertions.h
boost_spsc_queue.hpp boost_spsc_queue.hpp
Console.h Console.h
@ -81,7 +82,6 @@ target_sources(common PRIVATE
RedtapeWindows.h RedtapeWindows.h
RwMutex.h RwMutex.h
SafeArray.h SafeArray.h
ScopedAlloc.h
ScopedGuard.h ScopedGuard.h
ScopedPtrMT.h ScopedPtrMT.h
SettingsInterface.h SettingsInterface.h

View File

@ -277,4 +277,4 @@ extern wxString fromAscii(const char* src);
#include "common/Assertions.h" #include "common/Assertions.h"
#include "common/Exceptions.h" #include "common/Exceptions.h"
#include "common/ScopedAlloc.h" #include "common/AlignedMalloc.h"

View File

@ -19,7 +19,7 @@
#include <wx/tokenzr.h> #include <wx/tokenzr.h>
#include "common/Dependencies.h" #include "common/Dependencies.h"
#include "common/SafeArray.h" #include "common/SafeArray.h"
#include "common/ScopedAlloc.h" #include "common/AlignedMalloc.h"
#if _WIN32 #if _WIN32
#define WX_STR(str) (str.wc_str()) #define WX_STR(str) (str.wc_str())
@ -132,7 +132,7 @@ struct ParsedAssignmentString
// accepts Ascii/UTF8 only. // accepts Ascii/UTF8 only.
// //
typedef ScopedAlignedAlloc<char, 16> CharBufferType; typedef AlignedBuffer<char, 16> CharBufferType;
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// FastFormatAscii // FastFormatAscii
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(SolutionDir)common\vsprops\BaseProjectConfig.props" /> <Import Project="$(SolutionDir)common\vsprops\BaseProjectConfig.props" />
<Import Project="$(SolutionDir)common\vsprops\WinSDK.props" /> <Import Project="$(SolutionDir)common\vsprops\WinSDK.props" />
@ -100,6 +100,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="Align.h" /> <ClInclude Include="Align.h" />
<ClInclude Include="AlignedMalloc.h" />
<ClInclude Include="BitCast.h" /> <ClInclude Include="BitCast.h" />
<ClInclude Include="EmbeddedImage.h" /> <ClInclude Include="EmbeddedImage.h" />
<ClInclude Include="boost_spsc_queue.hpp" /> <ClInclude Include="boost_spsc_queue.hpp" />
@ -107,7 +108,6 @@
<ClInclude Include="GL\Context.h" /> <ClInclude Include="GL\Context.h" />
<ClInclude Include="GL\ContextWGL.h" /> <ClInclude Include="GL\ContextWGL.h" />
<ClInclude Include="GL\StreamBuffer.h" /> <ClInclude Include="GL\StreamBuffer.h" />
<ClInclude Include="ScopedAlloc.h" />
<ClInclude Include="ScopedGuard.h" /> <ClInclude Include="ScopedGuard.h" />
<ClInclude Include="StringUtil.h" /> <ClInclude Include="StringUtil.h" />
<ClInclude Include="SettingsInterface.h" /> <ClInclude Include="SettingsInterface.h" />

View File

@ -132,6 +132,9 @@
</ClCompile> </ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="AlignedMalloc.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Assertions.h"> <ClInclude Include="Assertions.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
@ -222,9 +225,6 @@
<ClInclude Include="SafeArray.h"> <ClInclude Include="SafeArray.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="ScopedAlloc.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="emitter\implement\simd_arithmetic.h"> <ClInclude Include="emitter\implement\simd_arithmetic.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>

View File

@ -452,8 +452,8 @@ void SysState_ComponentFreezeIn(pxInputStream& infp, SysState_Component comp)
return; return;
} }
ScopedAlloc<u8> data(fP.size); auto data = std::make_unique<u8[]>(fP.size);
fP.data = data.GetPtr(); fP.data = data.get();
infp.Read(fP.data, fP.size); infp.Read(fP.data, fP.size);
if (comp.freeze(FreezeAction::Load, &fP) != 0) if (comp.freeze(FreezeAction::Load, &fP) != 0)