/[pcsx2_0.9.7]/trunk/common/include/Utilities/SafeArray.inl
ViewVC logotype

Contents of /trunk/common/include/Utilities/SafeArray.inl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 280 - (show annotations) (download)
Thu Dec 23 12:02:12 2010 UTC (9 years, 1 month ago) by william
File size: 7913 byte(s)
re-commit (had local access denied errors when committing)
1 /* PCSX2 - PS2 Emulator for PCs
2 * Copyright (C) 2002-2010 PCSX2 Dev Team
3 *
4 * PCSX2 is free software: you can redistribute it and/or modify it under the terms
5 * of the GNU Lesser General Public License as published by the Free Software Found-
6 * ation, either version 3 of the License, or (at your option) any later version.
7 *
8 * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 * PURPOSE. See the GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License along with PCSX2.
13 * If not, see <http://www.gnu.org/licenses/>.
14 */
15
16 #pragma once
17
18 #include "MemcpyFast.h"
19 #include "SafeArray.h"
20
21 // Internal constructor for use by derived classes. This allows a derived class to
22 // use its own memory allocation (with an aligned memory, for example).
23 // Throws:
24 // Exception::OutOfMemory if the allocated_mem pointer is NULL.
25 template< typename T >
26 SafeArray<T>::SafeArray( const wxChar* name, T* allocated_mem, int initSize )
27 : Name( name )
28 {
29 ChunkSize = DefaultChunkSize;
30 m_ptr = allocated_mem;
31 m_size = initSize;
32
33 if( m_ptr == NULL )
34 throw Exception::OutOfMemory(name)
35 .SetDiagMsg(wxsFormat(L"Called from 'SafeArray::ctor' [size=%d]", initSize));
36 }
37
38 template< typename T >
39 T* SafeArray<T>::_virtual_realloc( int newsize )
40 {
41 T* retval = (T*)((m_ptr == NULL) ?
42 malloc( newsize * sizeof(T) ) :
43 realloc( m_ptr, newsize * sizeof(T) )
44 );
45
46 if( IsDebugBuild )
47 {
48 // Zero everything out to 0xbaadf00d, so that its obviously uncleared
49 // to a debuggee
50
51 u32* fill = (u32*)&retval[m_size];
52 const u32* end = (u32*)((((uptr)&retval[newsize-1])-3) & ~0x3);
53 for( ; fill<end; ++fill ) *fill = 0xbaadf00d;
54 }
55
56 return retval;
57 }
58
59 template< typename T >
60 SafeArray<T>::~SafeArray() throw()
61 {
62 safe_free( m_ptr );
63 }
64
65 template< typename T >
66 SafeArray<T>::SafeArray( const wxChar* name )
67 : Name( name )
68 {
69 ChunkSize = DefaultChunkSize;
70 m_ptr = NULL;
71 m_size = 0;
72 }
73
74 template< typename T >
75 SafeArray<T>::SafeArray( int initialSize, const wxChar* name )
76 : Name( name )
77 {
78 ChunkSize = DefaultChunkSize;
79 m_ptr = (initialSize==0) ? NULL : (T*)malloc( initialSize * sizeof(T) );
80 m_size = initialSize;
81
82 if( (initialSize != 0) && (m_ptr == NULL) )
83 throw Exception::OutOfMemory(name)
84 .SetDiagMsg(wxsFormat(L"Called from 'SafeArray::ctor' [size=%d]", initialSize));
85 }
86
87 // Clears the contents of the array to zero, and frees all memory allocations.
88 template< typename T >
89 void SafeArray<T>::Dispose()
90 {
91 m_size = 0;
92 safe_free( m_ptr );
93 }
94
95 template< typename T >
96 T* SafeArray<T>::_getPtr( uint i ) const
97 {
98 IndexBoundsAssumeDev( Name.c_str(), i, m_size );
99 return &m_ptr[i];
100 }
101
102 // reallocates the array to the explicit size. Can be used to shrink or grow an
103 // array, and bypasses the internal threshold growth indicators.
104 template< typename T >
105 void SafeArray<T>::ExactAlloc( int newsize )
106 {
107 if( newsize == m_size ) return;
108
109 m_ptr = _virtual_realloc( newsize );
110 if( m_ptr == NULL )
111 throw Exception::OutOfMemory(Name)
112 .SetDiagMsg(wxsFormat(L"Called from 'SafeArray::ExactAlloc' [oldsize=%d] [newsize=%d]", m_size, newsize));
113
114 m_size = newsize;
115 }
116
117 template< typename T >
118 SafeArray<T>* SafeArray<T>::Clone() const
119 {
120 SafeArray<T>* retval = new SafeArray<T>( m_size );
121 memcpy_fast( retval->GetPtr(), m_ptr, sizeof(T) * m_size );
122 return retval;
123 }
124
125
126 // --------------------------------------------------------------------------------------
127 // SafeAlignedArray<T> (implementations)
128 // --------------------------------------------------------------------------------------
129
130 template< typename T, uint Alignment >
131 T* SafeAlignedArray<T,Alignment>::_virtual_realloc( int newsize )
132 {
133 return (T*)( ( this->m_ptr == NULL ) ?
134 _aligned_malloc( newsize * sizeof(T), Alignment ) :
135 _aligned_realloc( this->m_ptr, newsize * sizeof(T), Alignment )
136 );
137 }
138
139 // Appends "(align: xx)" to the name of the allocation in devel builds.
140 // Maybe useful,maybe not... no harm in attaching it. :D
141
142 template< typename T, uint Alignment >
143 SafeAlignedArray<T,Alignment>::~SafeAlignedArray() throw()
144 {
145 safe_aligned_free( this->m_ptr );
146 // mptr is set to null, so the parent class's destructor won't re-free it.
147 }
148
149 template< typename T, uint Alignment >
150 SafeAlignedArray<T,Alignment>::SafeAlignedArray( int initialSize, const wxChar* name ) :
151 SafeArray<T>::SafeArray(
152 name,
153 (T*)_aligned_malloc( initialSize * sizeof(T), Alignment ),
154 initialSize
155 )
156 {
157 }
158
159 template< typename T, uint Alignment >
160 SafeAlignedArray<T,Alignment>* SafeAlignedArray<T,Alignment>::Clone() const
161 {
162 SafeAlignedArray<T,Alignment>* retval = new SafeAlignedArray<T,Alignment>( this->m_size );
163 memcpy_fast( retval->GetPtr(), this->m_ptr, sizeof(T) * this->m_size );
164 return retval;
165 }
166
167 // --------------------------------------------------------------------------------------
168 // SafeList<T> (implementations)
169 // --------------------------------------------------------------------------------------
170
171 template< typename T >
172 T* SafeList<T>::_virtual_realloc( int newsize )
173 {
174 return (T*)realloc( m_ptr, newsize * sizeof(T) );
175 }
176
177 template< typename T >
178 SafeList<T>::~SafeList() throw()
179 {
180 safe_free( m_ptr );
181 }
182
183 template< typename T >
184 SafeList<T>::SafeList( const wxChar* name )
185 : Name( name )
186 {
187 ChunkSize = DefaultChunkSize;
188 m_ptr = NULL;
189 m_allocsize = 0;
190 m_length = 0;
191 }
192
193 template< typename T >
194 SafeList<T>::SafeList( int initialSize, const wxChar* name )
195 : Name( name )
196 {
197 ChunkSize = DefaultChunkSize;
198 m_allocsize = initialSize;
199 m_length = 0;
200 m_ptr = (T*)malloc( initialSize * sizeof(T) );
201
202 if( m_ptr == NULL )
203 throw Exception::OutOfMemory(Name)
204 .SetDiagMsg(wxsFormat(L"called from 'SafeList::ctor' [length=%d]", m_length));
205
206 for( int i=0; i<m_allocsize; ++i )
207 {
208 new (&m_ptr[i]) T();
209 }
210
211 }
212
213 template< typename T >
214 T* SafeList<T>::_getPtr( uint i ) const
215 {
216 IndexBoundsAssumeDev( Name.c_str(), i, m_length );
217 return &m_ptr[i];
218 }
219
220 // Ensures that the allocation is large enough to fit data of the
221 // amount requested. The memory allocation is not resized smaller.
222 template< typename T >
223 void SafeList<T>::MakeRoomFor( int blockSize )
224 {
225 if( blockSize > m_allocsize )
226 {
227 const int newalloc = blockSize + ChunkSize;
228 m_ptr = _virtual_realloc( newalloc );
229 if( m_ptr == NULL )
230 throw Exception::OutOfMemory(Name)
231 .SetDiagMsg(wxsFormat(L"Called from 'SafeList::MakeRoomFor' [oldlen=%d] [newlen=%d]", m_length, blockSize));
232
233 for( ; m_allocsize<newalloc; ++m_allocsize )
234 {
235 new (&m_ptr[m_allocsize]) T();
236 }
237 }
238 }
239
240 // Appends an item to the end of the list and returns a handle to it.
241 template< typename T >
242 T& SafeList<T>::New()
243 {
244 _MakeRoomFor_threshold( m_length + 1 );
245 return m_ptr[m_length++];
246 }
247
248 template< typename T >
249 int SafeList<T>::Add( const T& src )
250 {
251 _MakeRoomFor_threshold( m_length + 1 );
252 m_ptr[m_length] = src;
253 return m_length++;
254 }
255
256 // Same as Add, but returns the handle of the new object instead of it's array index.
257 template< typename T >
258 T& SafeList<T>::AddNew( const T& src )
259 {
260 _MakeRoomFor_threshold( m_length + 1 );
261 m_ptr[m_length] = src;
262 return m_ptr[m_length];
263 }
264
265 // Performs a standard array-copy removal of the given item. All items past the
266 // given item are copied over.
267 // DevBuilds : Generates assertion if the index is invalid.
268 template< typename T >
269 void SafeList<T>::Remove( int index )
270 {
271 IndexBoundsAssumeDev( Name.c_str(), index, m_length );
272
273 int copylen = m_length - index;
274 if( copylen > 0 )
275 memcpy_fast( &m_ptr[index], &m_ptr[index+1], copylen );
276 }
277
278 template< typename T >
279 SafeList<T>* SafeList<T>::Clone() const
280 {
281 SafeList<T>* retval = new SafeList<T>( m_length );
282 memcpy_fast( retval->m_ptr, m_ptr, sizeof(T) * m_length );
283 return retval;
284 }
285
286 template< typename T >
287 void SafeList<T>::_MakeRoomFor_threshold( int newsize )
288 {
289 MakeRoomFor( newsize + ChunkSize );
290 }

  ViewVC Help
Powered by ViewVC 1.1.22