/[pcsx2_0.9.7]/trunk/common/include/Utilities/ScopedAlloc.h
ViewVC logotype

Contents of /trunk/common/include/Utilities/ScopedAlloc.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 280 - (show annotations) (download)
Thu Dec 23 12:02:12 2010 UTC (9 years, 2 months ago) by william
File MIME type: text/plain
File size: 8288 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 "Exceptions.h"
19
20 // pxUSE_SECURE_MALLOC - enables bounds checking on scoped malloc allocations.
21
22 #ifndef pxUSE_SECURE_MALLOC
23 #define pxUSE_SECURE_MALLOC 0
24 #endif
25
26 //////////////////////////////////////////////////////////////////////////////////////////
27 // Safe deallocation macros -- checks pointer validity (non-null) when needed, and sets
28 // pointer to null after deallocation.
29
30 #define safe_delete( ptr ) \
31 ((void) (delete (ptr)), (ptr) = NULL)
32
33 #define safe_delete_array( ptr ) \
34 ((void) (delete[] (ptr)), (ptr) = NULL)
35
36 // No checks for NULL -- wxWidgets says it's safe to skip NULL checks and it runs on
37 // just about every compiler and libc implementation of any recentness.
38 #define safe_free( ptr ) \
39 ( (void) (free( ptr ), !!0), (ptr) = NULL )
40 //((void) (( ( (ptr) != NULL ) && (free( ptr ), !!0) ), (ptr) = NULL))
41
42 #define safe_fclose( ptr ) \
43 ((void) (( ( (ptr) != NULL ) && (fclose( ptr ), !!0) ), (ptr) = NULL))
44
45 // Implementation note: all known implementations of _aligned_free check the pointer for
46 // NULL status (our implementation under GCC, and microsoft's under MSVC), so no need to
47 // do it here.
48 #define safe_aligned_free( ptr ) \
49 ((void) ( _aligned_free( ptr ), (ptr) = NULL ))
50
51
52 extern void* __fastcall pcsx2_aligned_malloc(size_t size, size_t align);
53 extern void* __fastcall pcsx2_aligned_realloc(void* handle, size_t size, size_t align);
54 extern void pcsx2_aligned_free(void* pmem);
55
56 // aligned_malloc: Implement/declare linux equivalents here!
57 #if !defined(_MSC_VER) && !defined(HAVE_ALIGNED_MALLOC)
58 # define _aligned_malloc pcsx2_aligned_malloc
59 # define _aligned_free pcsx2_aligned_free
60 # define _aligned_realloc pcsx2_aligned_realloc
61 #endif
62
63 // --------------------------------------------------------------------------------------
64 // pxDoOutOfMemory
65 // --------------------------------------------------------------------------------------
66
67 typedef void FnType_OutOfMemory( uptr blocksize );
68 typedef FnType_OutOfMemory* Fnptr_OutOfMemory;
69
70 // This method is meant to be assigned by applications that link against pxWex. It is called
71 // (invoked) prior to most pxWex built-in memory/array classes throwing exceptions, and can be
72 // used by an application to remove unneeded memory allocations and/or reduce internal cache
73 // reserves.
74 //
75 // Example: PCSX2 uses several bloated recompiler code caches. Larger caches improve performance,
76 // however a rouge cache growth could cause memory constraints in the operating system. If an out-
77 // of-memory error occurs, PCSX2's implementation of this function attempts to reset all internal
78 // recompiler caches. This can typically free up 100-150 megs of memory, and will allow the app
79 // to continue running without crashing or hanging the operating system, etc.
80 //
81 extern Fnptr_OutOfMemory pxDoOutOfMemory;
82
83
84 // --------------------------------------------------------------------------------------
85 // BaseScopedAlloc
86 // --------------------------------------------------------------------------------------
87 // Base class that allows various ScopedMalloc types to be passed to functions that act
88 // on them.
89 //
90 // Rationale: This class and the derived varieties are provided as a simple autonomous self-
91 // destructing container for malloc. The entire class is almost completely dependency free,
92 // and thus can be included everywhere and anywhere without dependency hassles.
93 //
94 template< typename T >
95 class BaseScopedAlloc
96 {
97 protected:
98 T* m_buffer;
99 uint m_size;
100
101 public:
102 BaseScopedAlloc()
103 {
104 m_buffer = NULL;
105 m_size = 0;
106 }
107
108 virtual ~BaseScopedAlloc() throw()
109 {
110 //pxAssume(m_buffer==NULL);
111 }
112
113 public:
114 size_t GetSize() const { return m_size; }
115 size_t GetLength() const { return m_size; }
116
117 // Allocates the object to the specified size. If an existing allocation is in
118 // place, it is freed and replaced with the new allocation, and all data is lost.
119 // Parameter:
120 // newSize - size of the new allocation, in elements (not bytes!). If the specified
121 // size is 0, the the allocation is freed, same as calling Free().
122 virtual void Alloc( size_t newsize )=0;
123
124 // Re-sizes the allocation to the requested size, without any data loss.
125 // Parameter:
126 // newSize - size of the new allocation, in elements (not bytes!). If the specified
127 // size is 0, the the allocation is freed, same as calling Free().
128 virtual void Resize( size_t newsize )=0;
129
130 void Free()
131 {
132 Alloc( 0 );
133 }
134
135 // Makes enough room for the requested size. Existing data in the array is retained.
136 void MakeRoomFor( uint size )
137 {
138 if (size <= m_size) return;
139 Resize( size );
140 }
141
142 T* GetPtr( uint idx=0 ) const
143 {
144 #if pxUSE_SECURE_MALLOC
145 IndexBoundsAssumeDev( "ScopedAlloc", idx, m_size );
146 #endif
147 return &m_buffer[idx];
148 }
149
150 T& operator[]( uint idx )
151 {
152 #if pxUSE_SECURE_MALLOC
153 IndexBoundsAssumeDev( "ScopedAlloc", idx, m_size );
154 #endif
155 return m_buffer[idx];
156 }
157
158 const T& operator[]( uint idx ) const
159 {
160 #if pxUSE_SECURE_MALLOC
161 IndexBoundsAssumeDev( "ScopedAlloc", idx, m_size );
162 #endif
163 return m_buffer[idx];
164 }
165 };
166
167 // --------------------------------------------------------------------------------------
168 // ScopedAlloc
169 // --------------------------------------------------------------------------------------
170 // A simple container class for a standard malloc allocation. By default, no bounds checking
171 // is performed, and there is no option for enabling bounds checking. If bounds checking and
172 // other features are needed, use the more robust SafeArray<> instead.
173 //
174 // See docs for BaseScopedAlloc for details and rationale.
175 //
176 template< typename T >
177 class ScopedAlloc : public BaseScopedAlloc<T>
178 {
179 public:
180 ScopedAlloc( size_t size=0 ) : BaseScopedAlloc<T>()
181 {
182 Alloc(size);
183 }
184
185 virtual ~ScopedAlloc() throw()
186 {
187 Alloc(0);
188 }
189
190 virtual void Alloc( size_t newsize )
191 {
192 safe_free(this->m_buffer);
193 this->m_size = newsize;
194 if (!this->m_size) return;
195
196 this->m_buffer = (T*)malloc( this->m_size * sizeof(T) );
197 if (!this->m_buffer)
198 throw Exception::OutOfMemory("ScopedAlloc");
199 }
200
201 virtual void Resize( size_t newsize )
202 {
203 this->m_size = newsize;
204 this->m_buffer = (T*)realloc(this->m_buffer * sizeof(T), newsize);
205
206 if (!this->m_buffer)
207 throw Exception::OutOfMemory("ScopedAlloc::Resize");
208 }
209 };
210
211 // --------------------------------------------------------------------------------------
212 // ScopedAlignedAlloc
213 // --------------------------------------------------------------------------------------
214 // A simple container class for an aligned allocation. By default, no bounds checking is
215 // performed, and there is no option for enabling bounds checking. If bounds checking and
216 // other features are needed, use the more robust SafeArray<> instead.
217 //
218 // See docs for BaseScopedAlloc for details and rationale.
219 //
220 template< typename T, uint align >
221 class ScopedAlignedAlloc : public BaseScopedAlloc<T>
222 {
223 public:
224 ScopedAlignedAlloc( size_t size=0 ) : BaseScopedAlloc<T>()
225 {
226 Alloc(size);
227 }
228
229 virtual ~ScopedAlignedAlloc() throw()
230 {
231 Alloc(0);
232 }
233
234 virtual void Alloc( size_t newsize )
235 {
236 safe_aligned_free(this->m_buffer);
237 this->m_size = newsize;
238 if (!this->m_size) return;
239
240 this->m_buffer = (T*)_aligned_malloc( this->m_size * sizeof(T), align );
241 if (!this->m_buffer)
242 throw Exception::OutOfMemory(L"ScopedAlignedAlloc");
243 }
244
245 virtual void Resize( size_t newsize )
246 {
247 this->m_size = newsize;
248 this->m_buffer = (T*)_aligned_realloc(this->m_buffer, newsize * sizeof(T), align);
249
250 if (!this->m_buffer)
251 throw Exception::OutOfMemory(L"ScopedAlignedAlloc::Resize");
252 }
253 };

  ViewVC Help
Powered by ViewVC 1.1.22