os/ossrv/genericopenlibs/cppstdlib/stl/test/eh/nc_alloc.cpp
changeset 0 bde4ae8d615e
     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