ReactOS 0.4.15-dev-8241-g63935f8
nc_alloc.cpp
Go to the documentation of this file.
1/************************************************************************************************
2 NC_ALLOC.CPP
3
4 * Copyright (c) 1997
5 * Mark of the Unicorn, Inc.
6 *
7 * Permission to use, copy, modify, distribute and sell this software
8 * and its documentation for any purpose is hereby granted without fee,
9 * provided that the above copyright notice appear in all copies and
10 * that both that copyright notice and this permission notice appear
11 * in supporting documentation. Mark of the Unicorn makes no
12 * representations about the suitability of this software for any
13 * purpose. It is provided "as is" without express or implied warranty.
14
15************************************************************************************************/
16
17#include "nc_alloc.h"
18#include <string>
19
20#if defined (EH_NEW_HEADERS)
21# include <new>
22# include <cassert>
23# include <cstdlib>
24#else
25# include <assert.h>
26# include <stdlib.h>
27# include <new.h>
28#endif
29
30#if defined (EH_NEW_IOSTREAMS)
31# include <iostream>
32#else
33# include <iostream.h>
34#endif
35
36long alloc_count = 0;
37long object_count = 0;
39const char* TestController::current_test = "<unknown>";
40const char* TestController::current_test_category = "no category";
47
48//************************************************************************************************
51 return;
52
53 // throw if allocation would satisfy the threshold
55 // what about doing some standard new_handler() behavior here (to test it!) ???
56
57 // reset and simulate an out-of-memory failure
59#ifndef EH_NO_EXCEPTIONS
60 throw EH_STD::bad_alloc();
61#endif
62 }
63}
64
65#if defined (EH_HASHED_CONTAINERS_IMPLEMENTED)
66# if defined (__SGI_STL)
67# if defined (EH_NEW_HEADERS)
68# include <hash_set>
69# else
70# include <hash_set.h>
71# endif
72# elif defined (__MSL__)
73# include <hashset.h>
74# else
75# error what do I include to get hash_set?
76# endif
77#else
78# if defined (EH_NEW_HEADERS)
79# include <set>
80# else
81# include <set.h>
82# endif
83#endif
84
85#if !defined (EH_HASHED_CONTAINERS_IMPLEMENTED)
86typedef EH_STD::set<void*, EH_STD::less<void*> > allocation_set;
87#else
88
89USING_CSTD_NAME(size_t)
90
92 size_t operator()(void* x) const { return (size_t)x; }
93};
94
95typedef EH_STD::hash_set<void*, ::hash_void, EH_STD::equal_to<void*> > allocation_set;
96#endif
97
99 static allocation_set s;
100 return s;
101}
102
103// Prevents infinite recursion during allocation
104static bool using_alloc_set = false;
105
106#if !defined (NO_FAST_ALLOCATOR)
107//
108// FastAllocator -- speeds up construction of TestClass objects when
109// TESTCLASS_DEEP_DATA is enabled, and speeds up tracking of allocations
110// when the suite is run with the -t option.
111//
113public:
114 //FastAllocator() : mFree(0), mUsed(0) {}
115 static void *Allocate(size_t s) {
116 void *result = 0;
117
118 if (s <= sizeof(Block)) {
119 if (mFree != 0) {
120 result = mFree;
121 mFree = mFree->next;
122 }
123 else if (mBlocks != 0 && mUsed < kBlockCount) {
124 result = (void*)&mBlocks[mUsed++];
125 }
126 }
127 return result;
128 }
129
130 static bool Free(void* p) {
131 Block* b = (Block*)p;
132 if (mBlocks == 0 || b < mBlocks || b >= mBlocks + kBlockCount)
133 return false;
134 b->next = mFree;
135 mFree = b;
136 return true;
137 }
138
139 struct Block;
140 friend struct Block;
141
142 enum {
143 // Number of fast allocation blocks to create.
145
146 // You may need to adjust this number for your platform.
147 // A good choice will speed tests. A bad choice will still work.
148 kMinBlockSize = 48
149 };
150
151 struct Block {
152 union {
154 double dummy; // fbp - force alignment
156 };
157 };
158
159 static Block* mBlocks;
160 static Block *mFree;
161 static size_t mUsed;
162};
163
168
169
171#endif
172
173inline char* AllocateBlock(size_t s) {
174#if !defined (NO_FAST_ALLOCATOR)
175 char * const p = (char*)gFastAllocator.Allocate( s );
176 if (p != 0)
177 return p;
178#endif
179
180 return (char*)EH_CSTD::malloc(s);
181}
182
183static void* OperatorNew( size_t s ) {
184 if (!using_alloc_set) {
186 ++alloc_count;
187 }
188
189 char *p = AllocateBlock(s);
190
194 using_alloc_set = true;
195 bool inserted = alloc_set().insert(p).second;
196 // Suppress warning about unused variable.
197 inserted;
198 EH_ASSERT(inserted);
199 using_alloc_set = false;
200 }
201
202 return p;
203}
204
205void* _STLP_CALL operator new(size_t s)
206#ifdef EH_DELETE_HAS_THROW_SPEC
207throw(EH_STD::bad_alloc)
208#endif
209{ return OperatorNew( s ); }
210
211#ifdef EH_USE_NOTHROW
212void* _STLP_CALL operator new(size_t size, const EH_STD::nothrow_t&) throw() {
213 try {
214 return OperatorNew( size );
215 }
216 catch (...) {
217 return 0;
218 }
219}
220#endif
221
222#if 1 /* defined (EH_VECTOR_OPERATOR_NEW) */
223void* _STLP_CALL operator new[](size_t size ) throw(EH_STD::bad_alloc) {
224 return OperatorNew( size );
225}
226
227# ifdef EH_USE_NOTHROW
228void* _STLP_CALL operator new[](size_t size, const EH_STD::nothrow_t&) throw() {
229 try {
230 return OperatorNew(size);
231 }
232 catch (...) {
233 return 0;
234 }
235}
236# endif
237
238void _STLP_CALL operator delete[](void* ptr) throw()
239{ operator delete( ptr ); }
240#endif
241
242#if defined (EH_DELETE_HAS_THROW_SPEC)
243void _STLP_CALL operator delete(void* s) throw()
244#else
245void _STLP_CALL operator delete(void* s)
246#endif
247{
248 if ( s != 0 ) {
249 if ( !using_alloc_set ) {
250 --alloc_count;
251
253 using_alloc_set = true;
254 allocation_set::iterator p = alloc_set().find( (char*)s );
255 EH_ASSERT( p != alloc_set().end() );
256 alloc_set().erase( p );
257 using_alloc_set = false;
258 }
259 }
260# if ! defined (NO_FAST_ALLOCATOR)
261 if ( !gFastAllocator.Free( s ) )
262# endif
263 EH_CSTD::free(s);
264 }
265}
266
267#if defined (EH_DELETE_HAS_THROW_SPEC)
268void _STLP_CALL operator delete(void* s, uintptr_t) throw()
269#else
270void _STLP_CALL operator delete(void* s, uintptr_t)
271#endif
272{
273 ::operator delete(s);
274}
275
276/*===================================================================================
277 ClearAllocationSet (private helper)
278
279 EFFECTS: Empty the set of allocated blocks.
280====================================================================================*/
282 if (!using_alloc_set) {
283 using_alloc_set = true;
284 alloc_set().clear();
285 using_alloc_set = false;
286 }
287}
288
289
292
293 EH_ASSERT( !using_alloc_set || (alloc_count == static_cast<int>(alloc_set().size())) );
294
295 if (alloc_count != 0 || object_count != 0) {
296 EH_STD::cerr<<"\nEH TEST FAILURE !\n";
297 PrintTestName(true);
298 if (alloc_count)
299 EH_STD::cerr << "ERROR : " << alloc_count << " outstanding allocations.\n";
300 if (object_count)
301 EH_STD::cerr << "ERROR : " << object_count << " non-destroyed objects.\n";
303 return true;
304 }
305 return false;
306}
307
308
309
310/*===================================================================================
311 PrintTestName
312
313 EFFECTS: Prints information about the current test. If err is false, ends with
314 an ellipsis, because the test is ongoing. If err is true an error is being
315 reported, and the output ends with an endl.
316====================================================================================*/
317
320 EH_STD::cerr<<"["<<current_container<<"] :";
321 EH_STD::cerr<<"testing "<<current_test <<" (" << current_test_category <<")";
322 if (err)
323 EH_STD::cerr<<EH_STD::endl;
324 else
325 EH_STD::cerr<<" ... ";
326}
327
329 if (nc_verbose)
330 EH_STD::cerr<<(count+1)<<" try successful"<<EH_STD::endl;
331}
332
334 static long failure_threshold = kNotInExceptionTest;
335 return failure_threshold;
336}
#define USING_CSTD_NAME(name)
Definition: Prefix.h:310
#define EH_ASSERT
Definition: Prefix.h:37
#define _STLP_CALL
Definition: _bc.h:131
static Block * mBlocks
Definition: nc_alloc.cpp:159
static size_t mUsed
Definition: nc_alloc.cpp:161
static void * Allocate(size_t s)
Definition: nc_alloc.cpp:115
static bool Free(void *p)
Definition: nc_alloc.cpp:130
static Block * mFree
Definition: nc_alloc.cpp:160
unsigned int uintptr_t
Definition: crtdefs.h:321
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLdouble s
Definition: gl.h:2039
GLuint GLuint end
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLfloat GLfloat p
Definition: glext.h:8902
GLuint64EXT * result
Definition: glext.h:11304
#define b
Definition: ke_i.h:79
static PVOID ptr
Definition: dispmode.c:27
long alloc_count
Definition: nc_alloc.cpp:36
EH_STD::hash_set< void *, ::hash_void, EH_STD::equal_to< void * > > allocation_set
Definition: nc_alloc.cpp:95
TestController gTestController
Definition: nc_alloc.cpp:46
static bool using_alloc_set
Definition: nc_alloc.cpp:104
static void * OperatorNew(size_t s)
Definition: nc_alloc.cpp:183
char * AllocateBlock(size_t s)
Definition: nc_alloc.cpp:173
static FastAllocator gFastAllocator
Definition: nc_alloc.cpp:170
long object_count
Definition: nc_alloc.cpp:37
static allocation_set & alloc_set()
Definition: nc_alloc.cpp:98
long alloc_count
Definition: nc_alloc.cpp:36
void simulate_possible_failure()
Definition: nc_alloc.h:117
long object_count
Definition: nc_alloc.cpp:37
#define err(...)
char dummy2[kMinBlockSize]
Definition: nc_alloc.cpp:155
static const char * current_container
Definition: nc_alloc.h:104
static bool ReportLeaked()
Definition: nc_alloc.cpp:290
static bool nc_verbose
Definition: nc_alloc.h:105
static const char * current_test_category
Definition: nc_alloc.h:103
static const char * current_test
Definition: nc_alloc.h:102
static void PrintTestName(bool err=false)
Definition: nc_alloc.cpp:318
@ kNotInExceptionTest
Definition: nc_alloc.h:94
static void EndLeakDetection()
Definition: nc_alloc.h:158
static long & Failure_threshold()
Definition: nc_alloc.cpp:333
static bool TrackingEnabled()
Definition: nc_alloc.h:134
static bool track_allocations
Definition: nc_alloc.h:107
static bool LeakDetectionEnabled()
Definition: nc_alloc.h:154
static long possible_failure_count
Definition: nc_alloc.h:101
static bool leak_detection_enabled
Definition: nc_alloc.h:108
static void ReportSuccess(int)
Definition: nc_alloc.cpp:328
static void ClearAllocationSet()
Definition: nc_alloc.cpp:281
static void maybe_fail(long)
Definition: nc_alloc.cpp:49
static bool never_fail
Definition: nc_alloc.h:106
size_t operator()(void *x) const
Definition: nc_alloc.cpp:92
operator