1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/genericopenlibs/cppstdlib/stl/test/eh/nc_alloc.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,386 @@
1.4 +/************************************************************************************************
1.5 + NC_ALLOC.CPP
1.6 +
1.7 + * Portions Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
1.8 + *
1.9 + * Copyright (c) 1997
1.10 + * Mark of the Unicorn, Inc.
1.11 + *
1.12 + * Permission to use, copy, modify, distribute and sell this software
1.13 + * and its documentation for any purpose is hereby granted without fee,
1.14 + * provided that the above copyright notice appear in all copies and
1.15 + * that both that copyright notice and this permission notice appear
1.16 + * in supporting documentation. Mark of the Unicorn makes no
1.17 + * representations about the suitability of this software for any
1.18 + * purpose. It is provided "as is" without express or implied warranty.
1.19 +
1.20 +************************************************************************************************/
1.21 +
1.22 +#include "nc_alloc.h"
1.23 +#include <string>
1.24 +
1.25 +#if defined (EH_NEW_HEADERS)
1.26 +# include <new>
1.27 +# include <cassert>
1.28 +# include <cstdlib>
1.29 +#else
1.30 +# include <assert.h>
1.31 +# include <stdlib.h>
1.32 +# include <new.h>
1.33 +#endif
1.34 +
1.35 +#if defined (EH_NEW_IOSTREAMS)
1.36 +# include <iostream>
1.37 +#else
1.38 +# include <iostream.h>
1.39 +#endif
1.40 +
1.41 +long alloc_count = 0;
1.42 +long object_count = 0;
1.43 +long TestController::possible_failure_count = 0;
1.44 +const char* TestController::current_test = "<unknown>";
1.45 +const char* TestController::current_test_category = "no category";
1.46 +const char* TestController::current_container = 0;
1.47 +bool TestController::nc_verbose = true;
1.48 +bool TestController::never_fail = false;
1.49 +bool TestController::track_allocations = false;
1.50 +bool TestController::leak_detection_enabled = false;
1.51 +
1.52 +TestController gTestController;
1.53 +
1.54 +//************************************************************************************************
1.55 +void TestController::maybe_fail(long) {
1.56 + if (never_fail || Failure_threshold() == kNotInExceptionTest)
1.57 + return;
1.58 +
1.59 + // throw if allocation would satisfy the threshold
1.60 + if (possible_failure_count++ >= Failure_threshold()) {
1.61 + // what about doing some standard new_handler() behavior here (to test it!) ???
1.62 +
1.63 + // reset and simulate an out-of-memory failure
1.64 + Failure_threshold() = kNotInExceptionTest;
1.65 +#ifndef EH_NO_EXCEPTIONS
1.66 + throw EH_STD::bad_alloc();
1.67 +#endif
1.68 + }
1.69 +}
1.70 +
1.71 +#if defined (EH_HASHED_CONTAINERS_IMPLEMENTED)
1.72 +# if defined (__SGI_STL)
1.73 +# if defined (EH_NEW_HEADERS)
1.74 +# include <hash_set>
1.75 +# else
1.76 +# include <hash_set.h>
1.77 +# endif
1.78 +# elif defined (__MSL__)
1.79 +# include <hashset.h>
1.80 +# else
1.81 +# error what do I include to get hash_set?
1.82 +# endif
1.83 +#else
1.84 +# if defined (EH_NEW_HEADERS)
1.85 +# include <set>
1.86 +# else
1.87 +# include <set.h>
1.88 +# endif
1.89 +#endif
1.90 +
1.91 +#if !defined (EH_HASHED_CONTAINERS_IMPLEMENTED)
1.92 +typedef EH_STD::set<void*, EH_STD::less<void*> > allocation_set;
1.93 +#else
1.94 +
1.95 +USING_CSTD_NAME(size_t)
1.96 +
1.97 +struct hash_void {
1.98 + size_t operator()(void* x) const { return (size_t)x; }
1.99 +};
1.100 +
1.101 +typedef EH_STD::hash_set<void*, ::hash_void, EH_STD::equal_to<void*> > allocation_set;
1.102 +#endif
1.103 +
1.104 +static allocation_set& alloc_set() {
1.105 + static allocation_set s;
1.106 + return s;
1.107 +}
1.108 +
1.109 +// Prevents infinite recursion during allocation
1.110 +static bool using_alloc_set = false;
1.111 +
1.112 +#if !defined (NO_FAST_ALLOCATOR)
1.113 +//
1.114 +// FastAllocator -- speeds up construction of TestClass objects when
1.115 +// TESTCLASS_DEEP_DATA is enabled, and speeds up tracking of allocations
1.116 +// when the suite is run with the -t option.
1.117 +//
1.118 +class FastAllocator {
1.119 +public:
1.120 + //FastAllocator() : mFree(0), mUsed(0) {}
1.121 + static void *Allocate(size_t s) {
1.122 + void *result = 0;
1.123 +
1.124 + if (s <= sizeof(Block)) {
1.125 + if (mFree != 0) {
1.126 + result = mFree;
1.127 + mFree = mFree->next;
1.128 + }
1.129 + else if (mBlocks != 0 && mUsed < kBlockCount) {
1.130 + result = (void*)&mBlocks[mUsed++];
1.131 + }
1.132 + }
1.133 + return result;
1.134 + }
1.135 +
1.136 + static bool Free(void* p) {
1.137 + Block* b = (Block*)p;
1.138 + if (mBlocks == 0 || b < mBlocks || b >= mBlocks + kBlockCount)
1.139 + return false;
1.140 + b->next = mFree;
1.141 + mFree = b;
1.142 + return true;
1.143 + }
1.144 +
1.145 + struct Block;
1.146 + friend struct Block;
1.147 +
1.148 + enum {
1.149 + // Number of fast allocation blocks to create.
1.150 + kBlockCount = 1500,
1.151 +
1.152 + // You may need to adjust this number for your platform.
1.153 + // A good choice will speed tests. A bad choice will still work.
1.154 + kMinBlockSize = 48
1.155 + };
1.156 +
1.157 + struct Block {
1.158 + union {
1.159 + Block *next;
1.160 + double dummy; // fbp - force alignment
1.161 + char dummy2[kMinBlockSize];
1.162 + };
1.163 + };
1.164 +
1.165 + static Block* mBlocks;
1.166 + static Block *mFree;
1.167 + static size_t mUsed;
1.168 +};
1.169 +
1.170 +FastAllocator::Block *FastAllocator::mBlocks =
1.171 +(FastAllocator::Block*)EH_CSTD::calloc( sizeof(FastAllocator::Block), FastAllocator::kBlockCount );
1.172 +FastAllocator::Block *FastAllocator::mFree;
1.173 +size_t FastAllocator::mUsed;
1.174 +
1.175 +
1.176 +static FastAllocator gFastAllocator;
1.177 +#endif
1.178 +
1.179 +inline char* AllocateBlock(size_t s) {
1.180 +#if !defined (NO_FAST_ALLOCATOR)
1.181 + char * const p = (char*)gFastAllocator.Allocate( s );
1.182 + if (p != 0)
1.183 + return p;
1.184 +#endif
1.185 +
1.186 + return (char*)EH_CSTD::malloc(s);
1.187 +}
1.188 +
1.189 +static void* OperatorNew( size_t s ) {
1.190 + if (!using_alloc_set) {
1.191 + simulate_possible_failure();
1.192 + ++alloc_count;
1.193 + }
1.194 +
1.195 + char *p = AllocateBlock(s);
1.196 +
1.197 + if (gTestController.TrackingEnabled() &&
1.198 + gTestController.LeakDetectionEnabled() &&
1.199 + !using_alloc_set) {
1.200 + using_alloc_set = true;
1.201 + bool inserted = alloc_set().insert(p).second;
1.202 + EH_ASSERT(inserted);
1.203 + using_alloc_set = false;
1.204 + }
1.205 +
1.206 + return p;
1.207 +}
1.208 +#if 0 //sandeep
1.209 +void* _STLP_CALL operator new(size_t s)
1.210 +#ifdef EH_DELETE_HAS_THROW_SPEC
1.211 +throw(EH_STD::bad_alloc)
1.212 +#endif
1.213 +{ return OperatorNew( s ); }
1.214 +
1.215 +#ifdef EH_USE_NOTHROW
1.216 +void* _STLP_CALL operator new(size_t size, const EH_STD::nothrow_t&) throw() {
1.217 + try {
1.218 + return OperatorNew( size );
1.219 + }
1.220 + catch (...) {
1.221 + return 0;
1.222 + }
1.223 +}
1.224 +#endif
1.225 +
1.226 +#if defined (EH_VECTOR_OPERATOR_NEW)
1.227 +void* _STLP_CALL operator new[](size_t size ) throw(EH_STD::bad_alloc) {
1.228 + return OperatorNew( size );
1.229 +}
1.230 +
1.231 +# ifdef EH_USE_NOTHROW
1.232 +void* _STLP_CALL operator new[](size_t size, const EH_STD::nothrow_t&) throw() {
1.233 + try {
1.234 + return OperatorNew(size);
1.235 + }
1.236 + catch (...) {
1.237 + return 0;
1.238 + }
1.239 +}
1.240 +# endif
1.241 +
1.242 +void _STLP_CALL operator delete[](void* ptr) throw()
1.243 +{ operator delete( ptr ); }
1.244 +#endif
1.245 +
1.246 +#if defined (EH_DELETE_HAS_THROW_SPEC)
1.247 +void _STLP_CALL operator delete(void* s) throw()
1.248 +#else
1.249 +void _STLP_CALL operator delete(void* s)
1.250 +#endif
1.251 +{
1.252 + if ( s != 0 ) {
1.253 + if ( !using_alloc_set ) {
1.254 + --alloc_count;
1.255 +
1.256 + if ( gTestController.TrackingEnabled() && gTestController.LeakDetectionEnabled() ) {
1.257 + using_alloc_set = true;
1.258 + allocation_set::iterator p = alloc_set().find( (char*)s );
1.259 + EH_ASSERT( p != alloc_set().end() );
1.260 + alloc_set().erase( p );
1.261 + using_alloc_set = false;
1.262 + }
1.263 + }
1.264 +# if ! defined (NO_FAST_ALLOCATOR)
1.265 + if ( !gFastAllocator.Free( s ) )
1.266 +# endif
1.267 + EH_CSTD::free(s);
1.268 + }
1.269 +}
1.270 +#endif //sandeep
1.271 +
1.272 +
1.273 +/*===================================================================================
1.274 + ClearAllocationSet (private helper)
1.275 +
1.276 + EFFECTS: Empty the set of allocated blocks.
1.277 +====================================================================================*/
1.278 +void TestController::ClearAllocationSet() {
1.279 + if (!using_alloc_set) {
1.280 + using_alloc_set = true;
1.281 + alloc_set().clear();
1.282 + using_alloc_set = false;
1.283 + }
1.284 +}
1.285 +
1.286 +
1.287 +bool TestController::ReportLeaked() {
1.288 + EndLeakDetection();
1.289 +
1.290 + if (using_alloc_set)
1.291 + EH_ASSERT( alloc_count == static_cast<int>(alloc_set().size()) );
1.292 +
1.293 + if (alloc_count != 0 || object_count != 0) {
1.294 + EH_STD::cerr<<"\nEH TEST FAILURE !\n";
1.295 + PrintTestName(true);
1.296 + if (alloc_count)
1.297 + EH_STD::cerr << "ERROR : " << alloc_count << " outstanding allocations.\n";
1.298 + if (object_count)
1.299 + EH_STD::cerr << "ERROR : " << object_count << " non-destroyed objects.\n";
1.300 + alloc_count = object_count = 0;
1.301 + return true;
1.302 + }
1.303 + return false;
1.304 +}
1.305 +
1.306 +
1.307 +
1.308 +/*===================================================================================
1.309 + PrintTestName
1.310 +
1.311 + EFFECTS: Prints information about the current test. If err is false, ends with
1.312 + an ellipsis, because the test is ongoing. If err is true an error is being
1.313 + reported, and the output ends with an endl.
1.314 +====================================================================================*/
1.315 +
1.316 +void TestController::PrintTestName(bool err) {
1.317 + if (current_container)
1.318 + EH_STD::cerr<<"["<<current_container<<"] :";
1.319 + EH_STD::cerr<<"testing "<<current_test <<" (" << current_test_category <<")";
1.320 + if (err)
1.321 + EH_STD::cerr<<EH_STD::endl;
1.322 + else
1.323 + EH_STD::cerr<<" ... ";
1.324 +}
1.325 +
1.326 +void TestController::ReportSuccess(int count) {
1.327 + if (nc_verbose)
1.328 + EH_STD::cerr<<(count+1)<<" try successful"<<EH_STD::endl;
1.329 +}
1.330 +
1.331 +long& TestController::Failure_threshold() {
1.332 + static long failure_threshold = kNotInExceptionTest;
1.333 + return failure_threshold;
1.334 +}
1.335 +#if 0 // enable non inline functions
1.336 +void TestController::TrackAllocations(bool track) {
1.337 + track_allocations = track;
1.338 +}
1.339 +
1.340 +bool TestController::TrackingEnabled() {
1.341 + return track_allocations;
1.342 +}
1.343 +
1.344 + void TestController::SetFailureCountdown(long count) {
1.345 + Failure_threshold() = count;
1.346 + possible_failure_count = 0;
1.347 +}
1.348 +
1.349 +void TestController::CancelFailureCountdown() {
1.350 + Failure_threshold() = kNotInExceptionTest;
1.351 +}
1.352 +
1.353 +void TestController::BeginLeakDetection() {
1.354 + alloc_count = 0;
1.355 + object_count = 0;
1.356 + ClearAllocationSet();
1.357 + leak_detection_enabled = true;
1.358 +}
1.359 +
1.360 +bool TestController::LeakDetectionEnabled() {
1.361 + return leak_detection_enabled;
1.362 +}
1.363 +
1.364 +void TestController::EndLeakDetection() {
1.365 + leak_detection_enabled = false;
1.366 +}
1.367 +
1.368 +void TestController::SetCurrentTestCategory(const char* str) {
1.369 + current_test_category = str;
1.370 + if (nc_verbose)
1.371 + PrintTestName();
1.372 +}
1.373 +
1.374 +void TestController::SetCurrentContainer(const char* str) {
1.375 + current_container=str;
1.376 +}
1.377 +
1.378 +void TestController::SetCurrentTestName(const char* str) {
1.379 + current_test = str;
1.380 +}
1.381 +
1.382 +void TestController::SetVerbose(bool val) {
1.383 + nc_verbose = val;
1.384 +}
1.385 +
1.386 +void TestController::TurnOffExceptions() {
1.387 + never_fail = true;
1.388 +}
1.389 +#endif