mirror of https://github.com/PCSX2/pcsx2.git
Linux: Likely fix for gcc errors compiling SafeArray
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3602 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
d231c537b9
commit
d88cf47adb
|
@ -445,6 +445,10 @@
|
||||||
RelativePath="..\..\include\Utilities\SafeArray.h"
|
RelativePath="..\..\include\Utilities\SafeArray.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\include\Utilities\SafeArray.inl"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\include\Utilities\ScopedPtr.h"
|
RelativePath="..\..\include\Utilities\ScopedPtr.h"
|
||||||
>
|
>
|
||||||
|
|
|
@ -173,3 +173,14 @@ extern u64 GetTickFrequency();
|
||||||
extern u64 GetCPUTicks();
|
extern u64 GetCPUTicks();
|
||||||
|
|
||||||
extern wxString GetOSVersionString();
|
extern wxString GetOSVersionString();
|
||||||
|
|
||||||
|
extern void* __fastcall pcsx2_aligned_malloc(size_t size, size_t align);
|
||||||
|
extern void* __fastcall pcsx2_aligned_realloc(void* handle, size_t size, size_t align);
|
||||||
|
extern void pcsx2_aligned_free(void* pmem);
|
||||||
|
|
||||||
|
// aligned_malloc: Implement/declare linux equivalents here!
|
||||||
|
#if !defined(_MSC_VER) && !defined(HAVE_ALIGNED_MALLOC)
|
||||||
|
# define _aligned_malloc pcsx2_aligned_malloc
|
||||||
|
# define _aligned_free pcsx2_aligned_free
|
||||||
|
# define _aligned_realloc pcsx2_aligned_realloc
|
||||||
|
#endif
|
||||||
|
|
|
@ -15,18 +15,6 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "MemcpyFast.h"
|
|
||||||
|
|
||||||
extern void* __fastcall pcsx2_aligned_malloc(size_t size, size_t align);
|
|
||||||
extern void* __fastcall pcsx2_aligned_realloc(void* handle, size_t size, size_t align);
|
|
||||||
extern void pcsx2_aligned_free(void* pmem);
|
|
||||||
|
|
||||||
// aligned_malloc: Implement/declare linux equivalents here!
|
|
||||||
#if !defined(_MSC_VER) && !defined(HAVE_ALIGNED_MALLOC)
|
|
||||||
# define _aligned_malloc pcsx2_aligned_malloc
|
|
||||||
# define _aligned_free pcsx2_aligned_free
|
|
||||||
# define _aligned_realloc pcsx2_aligned_realloc
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Safe deallocation macros -- checks pointer validity (non-null) when needed, and sets
|
// Safe deallocation macros -- checks pointer validity (non-null) when needed, and sets
|
||||||
|
@ -60,9 +48,11 @@ extern void pcsx2_aligned_free(void* pmem);
|
||||||
#define safe_release( ptr ) \
|
#define safe_release( ptr ) \
|
||||||
((void) (( ( (ptr) != NULL ) && ((ptr)->Release(), !!0) ), (ptr) = NULL))
|
((void) (( ( (ptr) != NULL ) && ((ptr)->Release(), !!0) ), (ptr) = NULL))
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
// --------------------------------------------------------------------------------------
|
||||||
// Handy little class for allocating a resizable memory block, complete with
|
// SafeArray
|
||||||
// exception-based error handling and automatic cleanup.
|
// --------------------------------------------------------------------------------------
|
||||||
|
// Handy little class for allocating a resizable memory block, complete with exception
|
||||||
|
// error handling and automatic cleanup. A lightweight alternative to std::vector.
|
||||||
//
|
//
|
||||||
template< typename T >
|
template< typename T >
|
||||||
class SafeArray
|
class SafeArray
|
||||||
|
@ -81,71 +71,29 @@ protected:
|
||||||
int m_size; // size of the allocation of memory
|
int m_size; // size of the allocation of memory
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Internal constructor for use by derived classes. This allows a derived class to
|
SafeArray( const wxChar* name, T* allocated_mem, int initSize );
|
||||||
// use its own memory allocation (with an aligned memory, for example).
|
virtual T* _virtual_realloc( int newsize );
|
||||||
// Throws:
|
|
||||||
// Exception::OutOfMemory if the allocated_mem pointer is NULL.
|
// A safe array index fetcher. Asserts if the index is out of bounds (dev and debug
|
||||||
explicit SafeArray( const wxChar* name, T* allocated_mem, int initSize )
|
// builds only -- no bounds checking is done in release builds).
|
||||||
: Name( name )
|
T* _getPtr( uint i ) const
|
||||||
{
|
{
|
||||||
ChunkSize = DefaultChunkSize;
|
IndexBoundsCheckDev( Name.c_str(), i, m_size );
|
||||||
m_ptr = allocated_mem;
|
return &m_ptr[i];
|
||||||
m_size = initSize;
|
|
||||||
|
|
||||||
if( m_ptr == NULL )
|
|
||||||
throw Exception::OutOfMemory(name + wxsFormat(L" (SafeArray::constructor) [size=%d]", initSize));
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual T* _virtual_realloc( int newsize )
|
|
||||||
{
|
|
||||||
T* retval = (T*)((m_ptr == NULL) ?
|
|
||||||
malloc( newsize * sizeof(T) ) :
|
|
||||||
realloc( m_ptr, newsize * sizeof(T) )
|
|
||||||
);
|
|
||||||
|
|
||||||
if( IsDebugBuild )
|
|
||||||
{
|
|
||||||
// Zero everything out to 0xbaadf00d, so that its obviously uncleared
|
|
||||||
// to a debuggee
|
|
||||||
|
|
||||||
u32* fill = (u32*)&retval[m_size];
|
|
||||||
const u32* end = (u32*)((((uptr)&retval[newsize-1])-3) & ~0x3);
|
|
||||||
for( ; fill<end; ++fill ) *fill = 0xbaadf00d;
|
|
||||||
}
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~SafeArray()
|
virtual ~SafeArray() throw();
|
||||||
{
|
|
||||||
safe_free( m_ptr );
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit SafeArray( const wxChar* name=L"Unnamed" )
|
explicit SafeArray( const wxChar* name=L"Unnamed" );
|
||||||
: Name( name )
|
explicit SafeArray( int initialSize, const wxChar* name=L"Unnamed" );
|
||||||
{
|
|
||||||
ChunkSize = DefaultChunkSize;
|
|
||||||
m_ptr = NULL;
|
|
||||||
m_size = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit SafeArray( int initialSize, const wxChar* name=L"Unnamed" )
|
void Dispose();
|
||||||
: Name( name )
|
void ExactAlloc( int newsize );
|
||||||
|
void MakeRoomFor( int newsize )
|
||||||
{
|
{
|
||||||
ChunkSize = DefaultChunkSize;
|
if( newsize > m_size )
|
||||||
m_ptr = (initialSize==0) ? NULL : (T*)malloc( initialSize * sizeof(T) );
|
ExactAlloc( newsize );
|
||||||
m_size = initialSize;
|
|
||||||
|
|
||||||
if( (initialSize != 0) && (m_ptr == NULL) )
|
|
||||||
throw Exception::OutOfMemory(name + wxsFormat(L" (SafeArray::constructor) [size=%d]", initialSize));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clears the contents of the array to zero, and frees all memory allocations.
|
|
||||||
void Dispose()
|
|
||||||
{
|
|
||||||
m_size = 0;
|
|
||||||
safe_free( m_ptr );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsDisposed() const { return (m_ptr==NULL); }
|
bool IsDisposed() const { return (m_ptr==NULL); }
|
||||||
|
@ -155,29 +103,6 @@ public:
|
||||||
// Returns the size of the memory allocation in bytes.
|
// Returns the size of the memory allocation in bytes.
|
||||||
int GetSizeInBytes() const { return m_size * sizeof(T); }
|
int GetSizeInBytes() const { return m_size * sizeof(T); }
|
||||||
|
|
||||||
// reallocates the array to the explicit size. Can be used to shrink or grow an
|
|
||||||
// array, and bypasses the internal threshold growth indicators.
|
|
||||||
void ExactAlloc( int newsize )
|
|
||||||
{
|
|
||||||
if( newsize == m_size ) return;
|
|
||||||
|
|
||||||
m_ptr = _virtual_realloc( newsize );
|
|
||||||
if( m_ptr == NULL )
|
|
||||||
throw Exception::OutOfMemory(Name +
|
|
||||||
wxsFormat(L" (SafeArray::ExactAlloc) [oldsize=%d] [newsize=%d]", m_size, newsize)
|
|
||||||
);
|
|
||||||
|
|
||||||
m_size = newsize;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensures that the allocation is large enough to fit data of the
|
|
||||||
// amount requested. The memory allocation is not resized smaller.
|
|
||||||
void MakeRoomFor( int newsize )
|
|
||||||
{
|
|
||||||
if( newsize > m_size )
|
|
||||||
ExactAlloc( newsize );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extends the containment area of the array. Extensions are performed
|
// Extends the containment area of the array. Extensions are performed
|
||||||
// in chunks.
|
// in chunks.
|
||||||
void GrowBy( int items )
|
void GrowBy( int items )
|
||||||
|
@ -195,25 +120,7 @@ public:
|
||||||
T& operator[]( int idx ) { return *_getPtr( (uint)idx ); }
|
T& operator[]( int idx ) { return *_getPtr( (uint)idx ); }
|
||||||
const T& operator[]( int idx ) const { return *_getPtr( (uint)idx ); }
|
const T& operator[]( int idx ) const { return *_getPtr( (uint)idx ); }
|
||||||
|
|
||||||
virtual SafeArray<T>* Clone() const
|
virtual SafeArray<T>* Clone() const;
|
||||||
{
|
|
||||||
SafeArray<T>* retval = new SafeArray<T>( m_size );
|
|
||||||
memcpy_fast( retval->GetPtr(), m_ptr, sizeof(T) * m_size );
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// A safe array index fetcher. Throws an exception if the array index
|
|
||||||
// is outside the bounds of the array.
|
|
||||||
// Performance Considerations: This function adds quite a bit of overhead
|
|
||||||
// to array indexing and thus should be done infrequently if used in
|
|
||||||
// time-critical situations. Instead of using it from inside loops, cache
|
|
||||||
// the pointer into a local variable and use std (unsafe) C indexes.
|
|
||||||
T* _getPtr( uint i ) const
|
|
||||||
{
|
|
||||||
IndexBoundsCheckDev( Name.c_str(), i, m_size );
|
|
||||||
return &m_ptr[i];
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -244,45 +151,27 @@ protected:
|
||||||
uint m_length; // length of the array (active items, not buffer allocation)
|
uint m_length; // length of the array (active items, not buffer allocation)
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual T* _virtual_realloc( int newsize )
|
virtual T* _virtual_realloc( int newsize );
|
||||||
|
void _MakeRoomFor_threshold( int newsize );
|
||||||
|
|
||||||
|
T* _getPtr( uint i ) const
|
||||||
{
|
{
|
||||||
return (T*)realloc( m_ptr, newsize * sizeof(T) );
|
IndexBoundsCheckDev( Name.c_str(), i, m_length );
|
||||||
|
return &m_ptr[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~SafeList() throw()
|
virtual ~SafeList() throw();
|
||||||
{
|
explicit SafeList( const wxChar* name=L"Unnamed" );
|
||||||
safe_free( m_ptr );
|
explicit SafeList( int initialSize, const wxChar* name=L"Unnamed" );
|
||||||
}
|
virtual SafeList<T>* Clone() const;
|
||||||
|
|
||||||
explicit SafeList( const wxChar* name=L"Unnamed" )
|
void Remove( int index );
|
||||||
: Name( name )
|
void MakeRoomFor( int blockSize );
|
||||||
{
|
|
||||||
ChunkSize = DefaultChunkSize;
|
|
||||||
m_ptr = NULL;
|
|
||||||
m_allocsize = 0;
|
|
||||||
m_length = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit SafeList( int initialSize, const wxChar* name=L"Unnamed" )
|
T& New();
|
||||||
: Name( name )
|
int Add( const T& src );
|
||||||
{
|
T& AddNew( const T& src );
|
||||||
ChunkSize = DefaultChunkSize;
|
|
||||||
m_allocsize = initialSize;
|
|
||||||
m_length = 0;
|
|
||||||
m_ptr = (T*)malloc( initialSize * sizeof(T) );
|
|
||||||
|
|
||||||
if( m_ptr == NULL )
|
|
||||||
throw Exception::OutOfMemory(Name +
|
|
||||||
wxsFormat(L" (SafeList::Constructor) [length=%d]", m_length)
|
|
||||||
);
|
|
||||||
|
|
||||||
for( int i=0; i<m_allocsize; ++i )
|
|
||||||
{
|
|
||||||
new (&m_ptr[i]) T();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the size of the list, as according to the array type. This includes
|
// Returns the size of the list, as according to the array type. This includes
|
||||||
// mapped items only. The actual size of the allocation may differ.
|
// mapped items only. The actual size of the allocation may differ.
|
||||||
|
@ -297,26 +186,6 @@ public:
|
||||||
m_length = m_allocsize;
|
m_length = m_allocsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensures that the allocation is large enough to fit data of the
|
|
||||||
// amount requested. The memory allocation is not resized smaller.
|
|
||||||
void MakeRoomFor( int blockSize )
|
|
||||||
{
|
|
||||||
if( blockSize > m_allocsize )
|
|
||||||
{
|
|
||||||
const int newalloc = blockSize + ChunkSize;
|
|
||||||
m_ptr = _virtual_realloc( newalloc );
|
|
||||||
if( m_ptr == NULL )
|
|
||||||
throw Exception::OutOfMemory(Name +
|
|
||||||
wxsFormat(L" (SafeList::MakeRoomFor) [oldlen=%d] [newlen=%d]", m_length, blockSize)
|
|
||||||
);
|
|
||||||
|
|
||||||
for( ; m_allocsize<newalloc; ++m_allocsize )
|
|
||||||
{
|
|
||||||
new (&m_ptr[m_allocsize]) T();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GrowBy( int items )
|
void GrowBy( int items )
|
||||||
{
|
{
|
||||||
MakeRoomFor( m_length + ChunkSize + items + 1 );
|
MakeRoomFor( m_length + ChunkSize + items + 1 );
|
||||||
|
@ -328,13 +197,6 @@ public:
|
||||||
m_length = 0;
|
m_length = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Appends an item to the end of the list and returns a handle to it.
|
|
||||||
T& New()
|
|
||||||
{
|
|
||||||
_MakeRoomFor_threshold( m_length + 1 );
|
|
||||||
return m_ptr[m_length++];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gets an element of this memory allocation much as if it were an array.
|
// Gets an element of this memory allocation much as if it were an array.
|
||||||
// DevBuilds : Generates assertion if the index is invalid.
|
// DevBuilds : Generates assertion if the index is invalid.
|
||||||
T& operator[]( int idx ) { return *_getPtr( (uint)idx ); }
|
T& operator[]( int idx ) { return *_getPtr( (uint)idx ); }
|
||||||
|
@ -345,63 +207,10 @@ public:
|
||||||
|
|
||||||
T& GetLast() { return m_ptr[m_length-1]; }
|
T& GetLast() { return m_ptr[m_length-1]; }
|
||||||
const T& GetLast() const{ return m_ptr[m_length-1]; }
|
const T& GetLast() const{ return m_ptr[m_length-1]; }
|
||||||
|
|
||||||
int Add( const T& src )
|
|
||||||
{
|
|
||||||
_MakeRoomFor_threshold( m_length + 1 );
|
|
||||||
m_ptr[m_length] = src;
|
|
||||||
return m_length++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Same as Add, but returns the handle of the new object instead of it's array index.
|
|
||||||
T& AddNew( const T& src )
|
|
||||||
{
|
|
||||||
_MakeRoomFor_threshold( m_length + 1 );
|
|
||||||
m_ptr[m_length] = src;
|
|
||||||
return m_ptr[m_length];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Performs a standard array-copy removal of the given item. All items past the
|
|
||||||
// given item are copied over.
|
|
||||||
// DevBuilds : Generates assertion if the index is invalid.
|
|
||||||
void Remove( int index )
|
|
||||||
{
|
|
||||||
IndexBoundsCheckDev( Name.c_str(), index, m_length );
|
|
||||||
|
|
||||||
int copylen = m_length - index;
|
|
||||||
if( copylen > 0 )
|
|
||||||
memcpy_fast( &m_ptr[index], &m_ptr[index+1], copylen );
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual SafeList<T>* Clone() const
|
|
||||||
{
|
|
||||||
SafeList<T>* retval = new SafeList<T>( m_length );
|
|
||||||
memcpy_fast( retval->m_ptr, m_ptr, sizeof(T) * m_length );
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
void _MakeRoomFor_threshold( int newsize )
|
|
||||||
{
|
|
||||||
MakeRoomFor( newsize + ChunkSize );
|
|
||||||
}
|
|
||||||
|
|
||||||
// A safe array index fetcher. Throws an exception if the array index
|
|
||||||
// is outside the bounds of the array.
|
|
||||||
// Performance Considerations: This function adds quite a bit of overhead
|
|
||||||
// to array indexing and thus should be done infrequently if used in
|
|
||||||
// time-critical situations. Instead of using it from inside loops, cache
|
|
||||||
// the pointer into a local variable and use std (unsafe) C indexes.
|
|
||||||
T* _getPtr( uint i ) const
|
|
||||||
{
|
|
||||||
IndexBoundsCheckDev( Name.c_str(), i, m_length );
|
|
||||||
return &m_ptr[i];
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
// SafeAlignedArray class
|
// SafeAlignedArray<T>
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
// Handy little class for allocating a resizable memory block, complete with
|
// Handy little class for allocating a resizable memory block, complete with
|
||||||
// exception-based error handling and automatic cleanup.
|
// exception-based error handling and automatic cleanup.
|
||||||
|
@ -413,49 +222,19 @@ class SafeAlignedArray : public SafeArray<T>
|
||||||
typedef SafeArray<T> _parent;
|
typedef SafeArray<T> _parent;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
T* _virtual_realloc( int newsize )
|
T* _virtual_realloc( int newsize );
|
||||||
{
|
|
||||||
return (T*)( ( this->m_ptr == NULL ) ?
|
|
||||||
_aligned_malloc( newsize * sizeof(T), Alignment ) :
|
|
||||||
_aligned_realloc( this->m_ptr, newsize * sizeof(T), Alignment )
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Appends "(align: xx)" to the name of the allocation in devel builds.
|
|
||||||
// Maybe useful,maybe not... no harm in attaching it. :D
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using _parent::operator[];
|
using _parent::operator[];
|
||||||
|
|
||||||
virtual ~SafeAlignedArray()
|
virtual ~SafeAlignedArray();
|
||||||
{
|
|
||||||
safe_aligned_free( this->m_ptr );
|
|
||||||
// mptr is set to null, so the parent class's destructor won't re-free it.
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit SafeAlignedArray( const wxChar* name=L"Unnamed" ) :
|
explicit SafeAlignedArray( const wxChar* name=L"Unnamed" ) :
|
||||||
SafeArray<T>::SafeArray( name )
|
SafeArray<T>::SafeArray( name )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit SafeAlignedArray( int initialSize, const wxChar* name=L"Unnamed" ) :
|
explicit SafeAlignedArray( int initialSize, const wxChar* name=L"Unnamed" );
|
||||||
SafeArray<T>::SafeArray(
|
virtual SafeAlignedArray<T,Alignment>* Clone() const;
|
||||||
name,
|
|
||||||
(T*)_aligned_malloc( initialSize * sizeof(T), Alignment ),
|
|
||||||
initialSize
|
|
||||||
)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual SafeAlignedArray<T,Alignment>* Clone() const
|
|
||||||
{
|
|
||||||
SafeAlignedArray<T,Alignment>* retval = new SafeAlignedArray<T,Alignment>( this->m_size );
|
|
||||||
memcpy_fast( retval->GetPtr(), this->m_ptr, sizeof(T) * this->m_size );
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// For lack of a better place for now (they depend on SafeList so they can't go in StringUtil)
|
|
||||||
extern void SplitString( SafeList<wxString>& dest, const wxString& src, const wxString& delims );
|
|
||||||
extern wxString JoinString( const SafeList<wxString>& src, const wxString& separator );
|
|
||||||
|
|
|
@ -0,0 +1,277 @@
|
||||||
|
/* PCSX2 - PS2 Emulator for PCs
|
||||||
|
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||||
|
*
|
||||||
|
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||||
|
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||||
|
* ation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||||
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||||
|
* If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "MemcpyFast.h"
|
||||||
|
#include "SafeArray.h"
|
||||||
|
|
||||||
|
// Internal constructor for use by derived classes. This allows a derived class to
|
||||||
|
// use its own memory allocation (with an aligned memory, for example).
|
||||||
|
// Throws:
|
||||||
|
// Exception::OutOfMemory if the allocated_mem pointer is NULL.
|
||||||
|
template< typename T >
|
||||||
|
SafeArray<T>::SafeArray( const wxChar* name, T* allocated_mem, int initSize )
|
||||||
|
: Name( name )
|
||||||
|
{
|
||||||
|
ChunkSize = DefaultChunkSize;
|
||||||
|
m_ptr = allocated_mem;
|
||||||
|
m_size = initSize;
|
||||||
|
|
||||||
|
if( m_ptr == NULL )
|
||||||
|
throw Exception::OutOfMemory(name + wxsFormat(L" (SafeArray::constructor) [size=%d]", initSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
T* SafeArray<T>::_virtual_realloc( int newsize )
|
||||||
|
{
|
||||||
|
T* retval = (T*)((m_ptr == NULL) ?
|
||||||
|
malloc( newsize * sizeof(T) ) :
|
||||||
|
realloc( m_ptr, newsize * sizeof(T) )
|
||||||
|
);
|
||||||
|
|
||||||
|
if( IsDebugBuild )
|
||||||
|
{
|
||||||
|
// Zero everything out to 0xbaadf00d, so that its obviously uncleared
|
||||||
|
// to a debuggee
|
||||||
|
|
||||||
|
u32* fill = (u32*)&retval[m_size];
|
||||||
|
const u32* end = (u32*)((((uptr)&retval[newsize-1])-3) & ~0x3);
|
||||||
|
for( ; fill<end; ++fill ) *fill = 0xbaadf00d;
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
SafeArray<T>::~SafeArray() throw()
|
||||||
|
{
|
||||||
|
safe_free( m_ptr );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
SafeArray<T>::SafeArray( const wxChar* name=L"Unnamed" )
|
||||||
|
: Name( name )
|
||||||
|
{
|
||||||
|
ChunkSize = DefaultChunkSize;
|
||||||
|
m_ptr = NULL;
|
||||||
|
m_size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
SafeArray<T>::SafeArray( int initialSize, const wxChar* name=L"Unnamed" )
|
||||||
|
: Name( name )
|
||||||
|
{
|
||||||
|
ChunkSize = DefaultChunkSize;
|
||||||
|
m_ptr = (initialSize==0) ? NULL : (T*)malloc( initialSize * sizeof(T) );
|
||||||
|
m_size = initialSize;
|
||||||
|
|
||||||
|
if( (initialSize != 0) && (m_ptr == NULL) )
|
||||||
|
throw Exception::OutOfMemory(name + wxsFormat(L" (SafeArray::constructor) [size=%d]", initialSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clears the contents of the array to zero, and frees all memory allocations.
|
||||||
|
template< typename T >
|
||||||
|
void SafeArray<T>::Dispose()
|
||||||
|
{
|
||||||
|
m_size = 0;
|
||||||
|
safe_free( m_ptr );
|
||||||
|
}
|
||||||
|
|
||||||
|
// reallocates the array to the explicit size. Can be used to shrink or grow an
|
||||||
|
// array, and bypasses the internal threshold growth indicators.
|
||||||
|
template< typename T >
|
||||||
|
void SafeArray<T>::ExactAlloc( int newsize )
|
||||||
|
{
|
||||||
|
if( newsize == m_size ) return;
|
||||||
|
|
||||||
|
m_ptr = _virtual_realloc( newsize );
|
||||||
|
if( m_ptr == NULL )
|
||||||
|
throw Exception::OutOfMemory(Name +
|
||||||
|
wxsFormat(L" (SafeArray::ExactAlloc) [oldsize=%d] [newsize=%d]", m_size, newsize)
|
||||||
|
);
|
||||||
|
|
||||||
|
m_size = newsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
SafeArray<T>* SafeArray<T>::Clone() const
|
||||||
|
{
|
||||||
|
SafeArray<T>* retval = new SafeArray<T>( m_size );
|
||||||
|
memcpy_fast( retval->GetPtr(), m_ptr, sizeof(T) * m_size );
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------------
|
||||||
|
// SafeAlignedArray<T> (implementations)
|
||||||
|
// --------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template< typename T, uint Alignment >
|
||||||
|
T* SafeAlignedArray<T,Alignment>::_virtual_realloc( int newsize )
|
||||||
|
{
|
||||||
|
return (T*)( ( this->m_ptr == NULL ) ?
|
||||||
|
_aligned_malloc( newsize * sizeof(T), Alignment ) :
|
||||||
|
_aligned_realloc( this->m_ptr, newsize * sizeof(T), Alignment )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Appends "(align: xx)" to the name of the allocation in devel builds.
|
||||||
|
// Maybe useful,maybe not... no harm in attaching it. :D
|
||||||
|
|
||||||
|
template< typename T, uint Alignment >
|
||||||
|
SafeAlignedArray<T,Alignment>::~SafeAlignedArray()
|
||||||
|
{
|
||||||
|
safe_aligned_free( this->m_ptr );
|
||||||
|
// mptr is set to null, so the parent class's destructor won't re-free it.
|
||||||
|
}
|
||||||
|
|
||||||
|
template< typename T, uint Alignment >
|
||||||
|
SafeAlignedArray<T,Alignment>::SafeAlignedArray( int initialSize, const wxChar* name=L"Unnamed" ) :
|
||||||
|
SafeArray<T>::SafeArray(
|
||||||
|
name,
|
||||||
|
(T*)_aligned_malloc( initialSize * sizeof(T), Alignment ),
|
||||||
|
initialSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template< typename T, uint Alignment >
|
||||||
|
SafeAlignedArray<T,Alignment>* SafeAlignedArray<T,Alignment>::Clone() const
|
||||||
|
{
|
||||||
|
SafeAlignedArray<T,Alignment>* retval = new SafeAlignedArray<T,Alignment>( this->m_size );
|
||||||
|
memcpy_fast( retval->GetPtr(), this->m_ptr, sizeof(T) * this->m_size );
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------------
|
||||||
|
// SafeList<T> (implementations)
|
||||||
|
// --------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
T* SafeList<T>::_virtual_realloc( int newsize )
|
||||||
|
{
|
||||||
|
return (T*)realloc( m_ptr, newsize * sizeof(T) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
SafeList<T>::~SafeList() throw()
|
||||||
|
{
|
||||||
|
safe_free( m_ptr );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
SafeList<T>::SafeList( const wxChar* name=L"Unnamed" )
|
||||||
|
: Name( name )
|
||||||
|
{
|
||||||
|
ChunkSize = DefaultChunkSize;
|
||||||
|
m_ptr = NULL;
|
||||||
|
m_allocsize = 0;
|
||||||
|
m_length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
SafeList<T>::SafeList( int initialSize, const wxChar* name=L"Unnamed" )
|
||||||
|
: Name( name )
|
||||||
|
{
|
||||||
|
ChunkSize = DefaultChunkSize;
|
||||||
|
m_allocsize = initialSize;
|
||||||
|
m_length = 0;
|
||||||
|
m_ptr = (T*)malloc( initialSize * sizeof(T) );
|
||||||
|
|
||||||
|
if( m_ptr == NULL )
|
||||||
|
throw Exception::OutOfMemory(Name +
|
||||||
|
wxsFormat(L" (SafeList::Constructor) [length=%d]", m_length)
|
||||||
|
);
|
||||||
|
|
||||||
|
for( int i=0; i<m_allocsize; ++i )
|
||||||
|
{
|
||||||
|
new (&m_ptr[i]) T();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensures that the allocation is large enough to fit data of the
|
||||||
|
// amount requested. The memory allocation is not resized smaller.
|
||||||
|
template< typename T >
|
||||||
|
void SafeList<T>::MakeRoomFor( int blockSize )
|
||||||
|
{
|
||||||
|
if( blockSize > m_allocsize )
|
||||||
|
{
|
||||||
|
const int newalloc = blockSize + ChunkSize;
|
||||||
|
m_ptr = _virtual_realloc( newalloc );
|
||||||
|
if( m_ptr == NULL )
|
||||||
|
throw Exception::OutOfMemory(Name +
|
||||||
|
wxsFormat(L" (SafeList::MakeRoomFor) [oldlen=%d] [newlen=%d]", m_length, blockSize)
|
||||||
|
);
|
||||||
|
|
||||||
|
for( ; m_allocsize<newalloc; ++m_allocsize )
|
||||||
|
{
|
||||||
|
new (&m_ptr[m_allocsize]) T();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Appends an item to the end of the list and returns a handle to it.
|
||||||
|
template< typename T >
|
||||||
|
T& SafeList<T>::New()
|
||||||
|
{
|
||||||
|
_MakeRoomFor_threshold( m_length + 1 );
|
||||||
|
return m_ptr[m_length++];
|
||||||
|
}
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
int SafeList<T>::Add( const T& src )
|
||||||
|
{
|
||||||
|
_MakeRoomFor_threshold( m_length + 1 );
|
||||||
|
m_ptr[m_length] = src;
|
||||||
|
return m_length++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Same as Add, but returns the handle of the new object instead of it's array index.
|
||||||
|
template< typename T >
|
||||||
|
T& SafeList<T>::AddNew( const T& src )
|
||||||
|
{
|
||||||
|
_MakeRoomFor_threshold( m_length + 1 );
|
||||||
|
m_ptr[m_length] = src;
|
||||||
|
return m_ptr[m_length];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Performs a standard array-copy removal of the given item. All items past the
|
||||||
|
// given item are copied over.
|
||||||
|
// DevBuilds : Generates assertion if the index is invalid.
|
||||||
|
template< typename T >
|
||||||
|
void SafeList<T>::Remove( int index )
|
||||||
|
{
|
||||||
|
IndexBoundsCheckDev( Name.c_str(), index, m_length );
|
||||||
|
|
||||||
|
int copylen = m_length - index;
|
||||||
|
if( copylen > 0 )
|
||||||
|
memcpy_fast( &m_ptr[index], &m_ptr[index+1], copylen );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
SafeList<T>* SafeList<T>::Clone() const
|
||||||
|
{
|
||||||
|
SafeList<T>* retval = new SafeList<T>( m_length );
|
||||||
|
memcpy_fast( retval->m_ptr, m_ptr, sizeof(T) * m_length );
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
void SafeList<T>::_MakeRoomFor_threshold( int newsize )
|
||||||
|
{
|
||||||
|
MakeRoomFor( newsize + ChunkSize );
|
||||||
|
}
|
|
@ -109,10 +109,7 @@ public:
|
||||||
m_IsDisposed = true;
|
m_IsDisposed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is needed the C++ standard likes making life suck for programmers.
|
TlsVariable<T>& operator=( const T& src )
|
||||||
using BaseTlsVariable<T>::GetRef;
|
|
||||||
|
|
||||||
TlsVariable& operator=( const T& src )
|
|
||||||
{
|
{
|
||||||
GetRef() = src;
|
GetRef() = src;
|
||||||
return *this;
|
return *this;
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
|
|
||||||
#include "PrecompiledHeader.h"
|
#include "PrecompiledHeader.h"
|
||||||
#include "Threading.h"
|
#include "Threading.h"
|
||||||
|
#include "TlsVariable.inl"
|
||||||
|
#include "SafeArray.inl"
|
||||||
|
|
||||||
using namespace Threading;
|
using namespace Threading;
|
||||||
|
|
||||||
|
@ -23,8 +25,6 @@ using namespace Threading;
|
||||||
// system deadlock.
|
// system deadlock.
|
||||||
static const int MaxFormattedStringLength = 0x80000;
|
static const int MaxFormattedStringLength = 0x80000;
|
||||||
|
|
||||||
#include "TlsVariable.inl"
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
// FastFormatBuffers
|
// FastFormatBuffers
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -41,13 +41,6 @@ __forceinline wxString fromAscii( const char* src )
|
||||||
//
|
//
|
||||||
// Note: wxWidgets 2.9 / 3.0 has a wxSplit function, but we're using 2.8 so I had to make
|
// Note: wxWidgets 2.9 / 3.0 has a wxSplit function, but we're using 2.8 so I had to make
|
||||||
// my own.
|
// my own.
|
||||||
void SplitString( SafeList<wxString>& dest, const wxString& src, const wxString& delims )
|
|
||||||
{
|
|
||||||
wxStringTokenizer parts( src, delims );
|
|
||||||
while( parts.HasMoreTokens() )
|
|
||||||
dest.Add( parts.GetNextToken() );
|
|
||||||
}
|
|
||||||
|
|
||||||
void SplitString( wxArrayString& dest, const wxString& src, const wxString& delims, wxStringTokenizerMode mode )
|
void SplitString( wxArrayString& dest, const wxString& src, const wxString& delims, wxStringTokenizerMode mode )
|
||||||
{
|
{
|
||||||
wxStringTokenizer parts( src, delims, mode );
|
wxStringTokenizer parts( src, delims, mode );
|
||||||
|
@ -61,20 +54,6 @@ void SplitString( wxArrayString& dest, const wxString& src, const wxString& deli
|
||||||
//
|
//
|
||||||
// Note: wxWidgets 2.9 / 3.0 has a wxJoin function, but we're using 2.8 so I had to make
|
// Note: wxWidgets 2.9 / 3.0 has a wxJoin function, but we're using 2.8 so I had to make
|
||||||
// my own.
|
// my own.
|
||||||
wxString JoinString( const SafeList<wxString>& src, const wxString& separator )
|
|
||||||
{
|
|
||||||
wxString dest;
|
|
||||||
for( int i=0, len=src.GetLength(); i<len; ++i )
|
|
||||||
{
|
|
||||||
if( src[i].IsEmpty() ) continue;
|
|
||||||
if( !dest.IsEmpty() )
|
|
||||||
dest += separator;
|
|
||||||
dest += src[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
return dest;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString JoinString( const wxArrayString& src, const wxString& separator )
|
wxString JoinString( const wxArrayString& src, const wxString& separator )
|
||||||
{
|
{
|
||||||
wxString dest;
|
wxString dest;
|
||||||
|
|
|
@ -17,6 +17,10 @@
|
||||||
#include "pxRadioPanel.h"
|
#include "pxRadioPanel.h"
|
||||||
#include "pxStaticText.h"
|
#include "pxStaticText.h"
|
||||||
|
|
||||||
|
#include "SafeArray.inl"
|
||||||
|
|
||||||
|
template class SafeArray<RadioPanelObjects>;
|
||||||
|
|
||||||
// ===========================================================================================
|
// ===========================================================================================
|
||||||
// pxRadioPanel Implementations
|
// pxRadioPanel Implementations
|
||||||
// ===========================================================================================
|
// ===========================================================================================
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
#include "Elfheader.h"
|
#include "Elfheader.h"
|
||||||
#include "Counters.h"
|
#include "Counters.h"
|
||||||
|
|
||||||
|
#include "Utilities/SafeArray.inl"
|
||||||
|
|
||||||
using namespace R5900;
|
using namespace R5900;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "App.h"
|
#include "App.h"
|
||||||
#include "SaveState.h"
|
#include "SaveState.h"
|
||||||
#include "ThreadedZipTools.h"
|
#include "ThreadedZipTools.h"
|
||||||
|
#include "Utilities/SafeArray.inl"
|
||||||
|
|
||||||
|
|
||||||
BaseCompressThread::~BaseCompressThread() throw()
|
BaseCompressThread::~BaseCompressThread() throw()
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "MSWstuff.h"
|
#include "MSWstuff.h"
|
||||||
|
|
||||||
#include "Utilities/Console.h"
|
#include "Utilities/Console.h"
|
||||||
|
#include "Utilities/SafeArray.inl"
|
||||||
#include "DebugTools/Debug.h"
|
#include "DebugTools/Debug.h"
|
||||||
|
|
||||||
#include <wx/textfile.h>
|
#include <wx/textfile.h>
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "PrecompiledHeader.h"
|
#include "PrecompiledHeader.h"
|
||||||
#include "Utilities/SafeArray.h"
|
#include "Utilities/SafeArray.inl"
|
||||||
|
|
||||||
#include "MemoryCardFile.h"
|
#include "MemoryCardFile.h"
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "Dialogs/ModalPopups.h"
|
#include "Dialogs/ModalPopups.h"
|
||||||
|
|
||||||
#include "Utilities/ThreadingDialogs.h"
|
#include "Utilities/ThreadingDialogs.h"
|
||||||
|
#include "Utilities/SafeArray.inl"
|
||||||
|
|
||||||
// Allows us to force-disable threading for debugging/troubleshooting
|
// Allows us to force-disable threading for debugging/troubleshooting
|
||||||
static const bool DisableThreading =
|
static const bool DisableThreading =
|
||||||
|
|
Loading…
Reference in New Issue