--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/genericopenlibs/cppstdlib/stl/test/eh/nc_alloc.cpp Tue Feb 02 02:01:42 2010 +0200
@@ -0,0 +1,386 @@
+/************************************************************************************************
+ NC_ALLOC.CPP
+
+ * Portions Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
+ *
+ * Copyright (c) 1997
+ * Mark of the Unicorn, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Mark of the Unicorn makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+
+************************************************************************************************/
+
+#include "nc_alloc.h"
+#include <string>
+
+#if defined (EH_NEW_HEADERS)
+# include <new>
+# include <cassert>
+# include <cstdlib>
+#else
+# include <assert.h>
+# include <stdlib.h>
+# include <new.h>
+#endif
+
+#if defined (EH_NEW_IOSTREAMS)
+# include <iostream>
+#else
+# include <iostream.h>
+#endif
+
+long alloc_count = 0;
+long object_count = 0;
+long TestController::possible_failure_count = 0;
+const char* TestController::current_test = "<unknown>";
+const char* TestController::current_test_category = "no category";
+const char* TestController::current_container = 0;
+bool TestController::nc_verbose = true;
+bool TestController::never_fail = false;
+bool TestController::track_allocations = false;
+bool TestController::leak_detection_enabled = false;
+
+TestController gTestController;
+
+//************************************************************************************************
+void TestController::maybe_fail(long) {
+ if (never_fail || Failure_threshold() == kNotInExceptionTest)
+ return;
+
+ // throw if allocation would satisfy the threshold
+ if (possible_failure_count++ >= Failure_threshold()) {
+ // what about doing some standard new_handler() behavior here (to test it!) ???
+
+ // reset and simulate an out-of-memory failure
+ Failure_threshold() = kNotInExceptionTest;
+#ifndef EH_NO_EXCEPTIONS
+ throw EH_STD::bad_alloc();
+#endif
+ }
+}
+
+#if defined (EH_HASHED_CONTAINERS_IMPLEMENTED)
+# if defined (__SGI_STL)
+# if defined (EH_NEW_HEADERS)
+# include <hash_set>
+# else
+# include <hash_set.h>
+# endif
+# elif defined (__MSL__)
+# include <hashset.h>
+# else
+# error what do I include to get hash_set?
+# endif
+#else
+# if defined (EH_NEW_HEADERS)
+# include <set>
+# else
+# include <set.h>
+# endif
+#endif
+
+#if !defined (EH_HASHED_CONTAINERS_IMPLEMENTED)
+typedef EH_STD::set<void*, EH_STD::less<void*> > allocation_set;
+#else
+
+USING_CSTD_NAME(size_t)
+
+struct hash_void {
+ size_t operator()(void* x) const { return (size_t)x; }
+};
+
+typedef EH_STD::hash_set<void*, ::hash_void, EH_STD::equal_to<void*> > allocation_set;
+#endif
+
+static allocation_set& alloc_set() {
+ static allocation_set s;
+ return s;
+}
+
+// Prevents infinite recursion during allocation
+static bool using_alloc_set = false;
+
+#if !defined (NO_FAST_ALLOCATOR)
+//
+// FastAllocator -- speeds up construction of TestClass objects when
+// TESTCLASS_DEEP_DATA is enabled, and speeds up tracking of allocations
+// when the suite is run with the -t option.
+//
+class FastAllocator {
+public:
+ //FastAllocator() : mFree(0), mUsed(0) {}
+ static void *Allocate(size_t s) {
+ void *result = 0;
+
+ if (s <= sizeof(Block)) {
+ if (mFree != 0) {
+ result = mFree;
+ mFree = mFree->next;
+ }
+ else if (mBlocks != 0 && mUsed < kBlockCount) {
+ result = (void*)&mBlocks[mUsed++];
+ }
+ }
+ return result;
+ }
+
+ static bool Free(void* p) {
+ Block* b = (Block*)p;
+ if (mBlocks == 0 || b < mBlocks || b >= mBlocks + kBlockCount)
+ return false;
+ b->next = mFree;
+ mFree = b;
+ return true;
+ }
+
+ struct Block;
+ friend struct Block;
+
+ enum {
+ // Number of fast allocation blocks to create.
+ kBlockCount = 1500,
+
+ // You may need to adjust this number for your platform.
+ // A good choice will speed tests. A bad choice will still work.
+ kMinBlockSize = 48
+ };
+
+ struct Block {
+ union {
+ Block *next;
+ double dummy; // fbp - force alignment
+ char dummy2[kMinBlockSize];
+ };
+ };
+
+ static Block* mBlocks;
+ static Block *mFree;
+ static size_t mUsed;
+};
+
+FastAllocator::Block *FastAllocator::mBlocks =
+(FastAllocator::Block*)EH_CSTD::calloc( sizeof(FastAllocator::Block), FastAllocator::kBlockCount );
+FastAllocator::Block *FastAllocator::mFree;
+size_t FastAllocator::mUsed;
+
+
+static FastAllocator gFastAllocator;
+#endif
+
+inline char* AllocateBlock(size_t s) {
+#if !defined (NO_FAST_ALLOCATOR)
+ char * const p = (char*)gFastAllocator.Allocate( s );
+ if (p != 0)
+ return p;
+#endif
+
+ return (char*)EH_CSTD::malloc(s);
+}
+
+static void* OperatorNew( size_t s ) {
+ if (!using_alloc_set) {
+ simulate_possible_failure();
+ ++alloc_count;
+ }
+
+ char *p = AllocateBlock(s);
+
+ if (gTestController.TrackingEnabled() &&
+ gTestController.LeakDetectionEnabled() &&
+ !using_alloc_set) {
+ using_alloc_set = true;
+ bool inserted = alloc_set().insert(p).second;
+ EH_ASSERT(inserted);
+ using_alloc_set = false;
+ }
+
+ return p;
+}
+#if 0 //sandeep
+void* _STLP_CALL operator new(size_t s)
+#ifdef EH_DELETE_HAS_THROW_SPEC
+throw(EH_STD::bad_alloc)
+#endif
+{ return OperatorNew( s ); }
+
+#ifdef EH_USE_NOTHROW
+void* _STLP_CALL operator new(size_t size, const EH_STD::nothrow_t&) throw() {
+ try {
+ return OperatorNew( size );
+ }
+ catch (...) {
+ return 0;
+ }
+}
+#endif
+
+#if defined (EH_VECTOR_OPERATOR_NEW)
+void* _STLP_CALL operator new[](size_t size ) throw(EH_STD::bad_alloc) {
+ return OperatorNew( size );
+}
+
+# ifdef EH_USE_NOTHROW
+void* _STLP_CALL operator new[](size_t size, const EH_STD::nothrow_t&) throw() {
+ try {
+ return OperatorNew(size);
+ }
+ catch (...) {
+ return 0;
+ }
+}
+# endif
+
+void _STLP_CALL operator delete[](void* ptr) throw()
+{ operator delete( ptr ); }
+#endif
+
+#if defined (EH_DELETE_HAS_THROW_SPEC)
+void _STLP_CALL operator delete(void* s) throw()
+#else
+void _STLP_CALL operator delete(void* s)
+#endif
+{
+ if ( s != 0 ) {
+ if ( !using_alloc_set ) {
+ --alloc_count;
+
+ if ( gTestController.TrackingEnabled() && gTestController.LeakDetectionEnabled() ) {
+ using_alloc_set = true;
+ allocation_set::iterator p = alloc_set().find( (char*)s );
+ EH_ASSERT( p != alloc_set().end() );
+ alloc_set().erase( p );
+ using_alloc_set = false;
+ }
+ }
+# if ! defined (NO_FAST_ALLOCATOR)
+ if ( !gFastAllocator.Free( s ) )
+# endif
+ EH_CSTD::free(s);
+ }
+}
+#endif //sandeep
+
+
+/*===================================================================================
+ ClearAllocationSet (private helper)
+
+ EFFECTS: Empty the set of allocated blocks.
+====================================================================================*/
+void TestController::ClearAllocationSet() {
+ if (!using_alloc_set) {
+ using_alloc_set = true;
+ alloc_set().clear();
+ using_alloc_set = false;
+ }
+}
+
+
+bool TestController::ReportLeaked() {
+ EndLeakDetection();
+
+ if (using_alloc_set)
+ EH_ASSERT( alloc_count == static_cast<int>(alloc_set().size()) );
+
+ if (alloc_count != 0 || object_count != 0) {
+ EH_STD::cerr<<"\nEH TEST FAILURE !\n";
+ PrintTestName(true);
+ if (alloc_count)
+ EH_STD::cerr << "ERROR : " << alloc_count << " outstanding allocations.\n";
+ if (object_count)
+ EH_STD::cerr << "ERROR : " << object_count << " non-destroyed objects.\n";
+ alloc_count = object_count = 0;
+ return true;
+ }
+ return false;
+}
+
+
+
+/*===================================================================================
+ PrintTestName
+
+ EFFECTS: Prints information about the current test. If err is false, ends with
+ an ellipsis, because the test is ongoing. If err is true an error is being
+ reported, and the output ends with an endl.
+====================================================================================*/
+
+void TestController::PrintTestName(bool err) {
+ if (current_container)
+ EH_STD::cerr<<"["<<current_container<<"] :";
+ EH_STD::cerr<<"testing "<<current_test <<" (" << current_test_category <<")";
+ if (err)
+ EH_STD::cerr<<EH_STD::endl;
+ else
+ EH_STD::cerr<<" ... ";
+}
+
+void TestController::ReportSuccess(int count) {
+ if (nc_verbose)
+ EH_STD::cerr<<(count+1)<<" try successful"<<EH_STD::endl;
+}
+
+long& TestController::Failure_threshold() {
+ static long failure_threshold = kNotInExceptionTest;
+ return failure_threshold;
+}
+#if 0 // enable non inline functions
+void TestController::TrackAllocations(bool track) {
+ track_allocations = track;
+}
+
+bool TestController::TrackingEnabled() {
+ return track_allocations;
+}
+
+ void TestController::SetFailureCountdown(long count) {
+ Failure_threshold() = count;
+ possible_failure_count = 0;
+}
+
+void TestController::CancelFailureCountdown() {
+ Failure_threshold() = kNotInExceptionTest;
+}
+
+void TestController::BeginLeakDetection() {
+ alloc_count = 0;
+ object_count = 0;
+ ClearAllocationSet();
+ leak_detection_enabled = true;
+}
+
+bool TestController::LeakDetectionEnabled() {
+ return leak_detection_enabled;
+}
+
+void TestController::EndLeakDetection() {
+ leak_detection_enabled = false;
+}
+
+void TestController::SetCurrentTestCategory(const char* str) {
+ current_test_category = str;
+ if (nc_verbose)
+ PrintTestName();
+}
+
+void TestController::SetCurrentContainer(const char* str) {
+ current_container=str;
+}
+
+void TestController::SetCurrentTestName(const char* str) {
+ current_test = str;
+}
+
+void TestController::SetVerbose(bool val) {
+ nc_verbose = val;
+}
+
+void TestController::TurnOffExceptions() {
+ never_fail = true;
+}
+#endif