sl@0: #include sl@0: #include sl@0: sl@0: #include sl@0: sl@0: #include "cppunit/cppunit_proxy.h" sl@0: sl@0: #if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES) sl@0: using namespace std; sl@0: #endif sl@0: sl@0: // sl@0: // TestCase class sl@0: // sl@0: class AllocatorTest : public CPPUNIT_NS::TestCase sl@0: { sl@0: CPPUNIT_TEST_SUITE(AllocatorTest); sl@0: CPPUNIT_TEST(zero_allocation); sl@0: #if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) sl@0: CPPUNIT_TEST(bad_alloc_test); sl@0: #endif sl@0: #if defined (STLPORT) && defined (_STLP_THREADS) && defined (_STLP_USE_PERTHREAD_ALLOC) sl@0: CPPUNIT_TEST(per_thread_alloc); sl@0: #endif sl@0: CPPUNIT_TEST_SUITE_END(); sl@0: sl@0: protected: sl@0: void zero_allocation(); sl@0: void bad_alloc_test(); sl@0: void per_thread_alloc(); sl@0: }; sl@0: sl@0: CPPUNIT_TEST_SUITE_REGISTRATION(AllocatorTest); sl@0: sl@0: // sl@0: // tests implementation sl@0: // sl@0: void AllocatorTest::zero_allocation() sl@0: { sl@0: typedef allocator CharAllocator; sl@0: CharAllocator charAllocator; sl@0: sl@0: char* buf = charAllocator.allocate(0); sl@0: charAllocator.deallocate(buf, 0); sl@0: sl@0: charAllocator.deallocate(0, 0); sl@0: } sl@0: sl@0: #if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) sl@0: sl@0: struct BigStruct sl@0: { sl@0: char _data[4096]; sl@0: }; sl@0: sl@0: void AllocatorTest::bad_alloc_test() sl@0: { sl@0: typedef allocator BigStructAllocType; sl@0: BigStructAllocType bigStructAlloc; sl@0: sl@0: try { sl@0: //Lets try to allocate almost 4096 Go (on most of the platforms) of memory: sl@0: BigStructAllocType::pointer pbigStruct = bigStructAlloc.allocate(1024 * 1024 * 1024); sl@0: sl@0: //Allocation failed but no exception thrown sl@0: CPPUNIT_ASSERT( pbigStruct != 0 ); sl@0: } sl@0: catch (bad_alloc const&) { sl@0: } sl@0: catch (...) { sl@0: //We shouldn't be there: sl@0: //Not bad_alloc exception thrown. sl@0: CPPUNIT_ASSERT( false ); sl@0: } sl@0: } sl@0: #endif sl@0: sl@0: #if defined (STLPORT) && defined (_STLP_THREADS) && defined (_STLP_USE_PERTHREAD_ALLOC) sl@0: # include sl@0: sl@0: class SharedDatas sl@0: { sl@0: public: sl@0: typedef vector > thread_vector; sl@0: sl@0: SharedDatas(size_t nbElems) : threadVectors(nbElems, (thread_vector*)0) { sl@0: pthread_mutex_init(&mutex, 0); sl@0: pthread_cond_init(&condition, 0); sl@0: } sl@0: sl@0: ~SharedDatas() { sl@0: for (size_t i = 0; i < threadVectors.size(); ++i) { sl@0: delete threadVectors[i]; sl@0: } sl@0: } sl@0: sl@0: size_t initThreadVector() { sl@0: size_t ret; sl@0: sl@0: pthread_mutex_lock(&mutex); sl@0: sl@0: for (size_t i = 0; i < threadVectors.size(); ++i) { sl@0: if (threadVectors[i] == 0) { sl@0: threadVectors[i] = new thread_vector(); sl@0: ret = i; sl@0: break; sl@0: } sl@0: } sl@0: sl@0: if (ret != threadVectors.size() - 1) { sl@0: //We wait for other thread(s) to call this method too: sl@0: printf("Thread %d wait\n", ret); sl@0: pthread_cond_wait(&condition, &mutex); sl@0: } sl@0: else { sl@0: //We are the last thread calling this method, we signal this sl@0: //to the other thread(s) that might be waiting: sl@0: printf("Thread %d signal\n", ret); sl@0: pthread_cond_signal(&condition); sl@0: } sl@0: sl@0: pthread_mutex_unlock(&mutex); sl@0: sl@0: return ret; sl@0: } sl@0: sl@0: thread_vector& getThreadVector(size_t index) { sl@0: //We return other thread thread_vector instance: sl@0: return *threadVectors[(index + 1 == threadVectors.size()) ? 0 : index + 1]; sl@0: } sl@0: sl@0: private: sl@0: pthread_mutex_t mutex; sl@0: pthread_cond_t condition; sl@0: vector threadVectors; sl@0: }; sl@0: sl@0: void* f(void* pdatas) { sl@0: SharedDatas *psharedDatas = (SharedDatas*)pdatas; sl@0: sl@0: int threadIndex = psharedDatas->initThreadVector(); sl@0: sl@0: for (int i = 0; i < 100; ++i) { sl@0: psharedDatas->getThreadVector(threadIndex).push_back(i); sl@0: } sl@0: sl@0: return 0; sl@0: } sl@0: sl@0: void AllocatorTest::per_thread_alloc() sl@0: { sl@0: const size_t nth = 2; sl@0: SharedDatas datas(nth); sl@0: pthread_t t[nth]; sl@0: sl@0: size_t i; sl@0: for (i = 0; i < nth; ++i) { sl@0: pthread_create(&t[i], 0, f, &datas); sl@0: } sl@0: sl@0: for (i = 0; i < nth; ++i ) { sl@0: pthread_join(t[i], 0); sl@0: } sl@0: } sl@0: #endif