ReactOS  0.4.13-dev-563-g0561610
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 
36 long alloc_count = 0;
37 long object_count = 0;
39 const char* TestController::current_test = "<unknown>";
40 const char* TestController::current_test_category = "no category";
41 const char* TestController::current_container = 0;
42 bool TestController::nc_verbose = true;
43 bool TestController::never_fail = false;
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)
86 typedef EH_STD::set<void*, EH_STD::less<void*> > allocation_set;
87 #else
88 
89 USING_CSTD_NAME(size_t)
90 
92  size_t operator()(void* x) const { return (size_t)x; }
93 };
94 
95 typedef 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
104 static 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 //
113 public:
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;
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.
144  kBlockCount = 1500,
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.
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 
167 size_t FastAllocator::mUsed;
168 
169 
171 #endif
172 
173 inline 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 
183 static void* OperatorNew( size_t s ) {
184  if (!using_alloc_set) {
186  ++alloc_count;
187  }
188 
189  char *p = AllocateBlock(s);
190 
193  !using_alloc_set) {
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 
205 void* _STLP_CALL operator new(size_t s)
206 #ifdef EH_DELETE_HAS_THROW_SPEC
207 throw(EH_STD::bad_alloc)
208 #endif
209 { return OperatorNew( s ); }
210 
211 #ifdef EH_USE_NOTHROW
212 void* _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) */
223 void* _STLP_CALL operator new[](size_t size ) throw(EH_STD::bad_alloc) {
224  return OperatorNew( size );
225 }
226 
227 # ifdef EH_USE_NOTHROW
228 void* _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 
238 void _STLP_CALL operator delete[](void* ptr) throw()
239 { operator delete( ptr ); }
240 #endif
241 
242 #if defined (EH_DELETE_HAS_THROW_SPEC)
243 void _STLP_CALL operator delete(void* s) throw()
244 #else
245 void _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)
268 void _STLP_CALL operator delete(void* s, uintptr_t) throw()
269 #else
270 void _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 
319  if (current_container)
320  EH_STD::cerr<<"["<<current_container<<"] :";
321  EH_STD::cerr<<"testing "<<current_test <<" (" << current_test_category <<")";
322  if (err)
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 }
static void ClearAllocationSet()
Definition: nc_alloc.cpp:281
static void maybe_fail(long)
Definition: nc_alloc.cpp:49
static bool using_alloc_set
Definition: nc_alloc.cpp:104
static bool ReportLeaked()
Definition: nc_alloc.cpp:290
static bool track_allocations
Definition: nc_alloc.h:107
GLuint GLuint GLsizei count
Definition: gl.h:1545
TestController gTestController
Definition: nc_alloc.cpp:46
#define free
Definition: debug_ros.c:5
operator
static void PrintTestName(bool err=false)
Definition: nc_alloc.cpp:318
#define USING_CSTD_NAME(name)
Definition: Prefix.h:310
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLuint GLuint end
Definition: gl.h:1545
static bool LeakDetectionEnabled()
Definition: nc_alloc.h:154
size_t operator()(void *x) const
Definition: nc_alloc.cpp:92
static bool TrackingEnabled()
Definition: nc_alloc.h:134
basic_ostream< _CharT, _Traits > &_STLP_CALL endl(basic_ostream< _CharT, _Traits > &__os)
Definition: _ostream.h:357
static allocation_set & alloc_set()
Definition: nc_alloc.cpp:98
unsigned int uintptr_t
Definition: crtdefs.h:300
static PVOID ptr
Definition: dispmode.c:27
static size_t mUsed
Definition: nc_alloc.cpp:161
static void * Allocate(size_t s)
Definition: nc_alloc.cpp:115
static long possible_failure_count
Definition: nc_alloc.h:101
#define b
Definition: ke_i.h:79
long object_count
Definition: nc_alloc.cpp:37
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLsizeiptr size
Definition: glext.h:5919
_STLP_DECLSPEC _Stl_aligned_buffer< ostream > cerr
Definition: iostream.cpp:102
static const char * current_test
Definition: nc_alloc.h:102
static void EndLeakDetection()
Definition: nc_alloc.h:158
long alloc_count
Definition: nc_alloc.cpp:36
static bool never_fail
Definition: nc_alloc.h:106
static long & Failure_threshold()
Definition: nc_alloc.cpp:333
#define EH_ASSERT
Definition: Prefix.h:37
static bool leak_detection_enabled
Definition: nc_alloc.h:108
GLdouble s
Definition: gl.h:2039
#define err(...)
static FastAllocator gFastAllocator
Definition: nc_alloc.cpp:170
static Block * mFree
Definition: nc_alloc.cpp:160
static const char * current_container
Definition: nc_alloc.h:104
static const char * current_test_category
Definition: nc_alloc.h:103
void simulate_possible_failure()
Definition: nc_alloc.h:117
static bool Free(void *p)
Definition: nc_alloc.cpp:130
char dummy2[kMinBlockSize]
Definition: nc_alloc.cpp:155
static bool nc_verbose
Definition: nc_alloc.h:105
static Block * mBlocks
Definition: nc_alloc.cpp:159
#define calloc
Definition: rosglue.h:14
#define malloc
Definition: debug_ros.c:4
static void ReportSuccess(int)
Definition: nc_alloc.cpp:328
GLfloat GLfloat p
Definition: glext.h:8902
GLuint64EXT * result
Definition: glext.h:11304
char * AllocateBlock(size_t s)
Definition: nc_alloc.cpp:173
#define _STLP_CALL
Definition: _bc.h:131
EH_STD::hash_set< void *, ::hash_void, EH_STD::equal_to< void * > > allocation_set
Definition: nc_alloc.cpp:95
static void * OperatorNew(size_t s)
Definition: nc_alloc.cpp:183