os/ossrv/genericopenlibs/cppstdlib/stl/test/unit/allocator_test.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 #include <memory>
     2 #include <vector>
     3 
     4 #include <cstdio>
     5 
     6 #include "cppunit/cppunit_proxy.h"
     7 
     8 #if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES)
     9 using namespace std;
    10 #endif
    11 
    12 //
    13 // TestCase class
    14 //
    15 class AllocatorTest : public CPPUNIT_NS::TestCase
    16 {
    17   CPPUNIT_TEST_SUITE(AllocatorTest);
    18   CPPUNIT_TEST(zero_allocation);
    19 #if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
    20   CPPUNIT_TEST(bad_alloc_test);
    21 #endif
    22 #if defined (STLPORT) && defined (_STLP_THREADS) && defined (_STLP_USE_PERTHREAD_ALLOC)
    23   CPPUNIT_TEST(per_thread_alloc);
    24 #endif
    25   CPPUNIT_TEST_SUITE_END();
    26 
    27 protected:
    28   void zero_allocation();
    29   void bad_alloc_test();
    30   void per_thread_alloc();
    31 };
    32 
    33 CPPUNIT_TEST_SUITE_REGISTRATION(AllocatorTest);
    34 
    35 //
    36 // tests implementation
    37 //
    38 void AllocatorTest::zero_allocation()
    39 {
    40   typedef allocator<char> CharAllocator;
    41   CharAllocator charAllocator;
    42 
    43   char* buf = charAllocator.allocate(0);
    44   charAllocator.deallocate(buf, 0);
    45 
    46   charAllocator.deallocate(0, 0);
    47 }
    48 
    49 #if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
    50 
    51 struct BigStruct
    52 {
    53   char _data[4096];
    54 };
    55 
    56 void AllocatorTest::bad_alloc_test()
    57 {
    58   typedef allocator<BigStruct> BigStructAllocType;
    59   BigStructAllocType bigStructAlloc;
    60 
    61   try {
    62     //Lets try to allocate almost 4096 Go (on most of the platforms) of memory:
    63     BigStructAllocType::pointer pbigStruct = bigStructAlloc.allocate(1024 * 1024 * 1024);
    64 
    65     //Allocation failed but no exception thrown
    66     CPPUNIT_ASSERT( pbigStruct != 0 );
    67   }
    68   catch (bad_alloc const&) {
    69   }
    70   catch (...) {
    71     //We shouldn't be there:
    72     //Not bad_alloc exception thrown.
    73     CPPUNIT_ASSERT( false );
    74   }
    75 }
    76 #endif
    77 
    78 #if defined (STLPORT) && defined (_STLP_THREADS) && defined (_STLP_USE_PERTHREAD_ALLOC)
    79 #  include <pthread.h>
    80 
    81 class SharedDatas
    82 {
    83 public:
    84   typedef vector<int, per_thread_allocator<int> > thread_vector;
    85 
    86   SharedDatas(size_t nbElems) : threadVectors(nbElems, (thread_vector*)0) {
    87     pthread_mutex_init(&mutex, 0);
    88     pthread_cond_init(&condition, 0);
    89   }
    90 
    91   ~SharedDatas() {
    92     for (size_t i = 0; i < threadVectors.size(); ++i) {
    93       delete threadVectors[i];
    94     }
    95   }
    96 
    97   size_t initThreadVector() {
    98     size_t ret;
    99 
   100     pthread_mutex_lock(&mutex);
   101 
   102     for (size_t i = 0; i < threadVectors.size(); ++i) {
   103       if (threadVectors[i] == 0) {
   104         threadVectors[i] = new thread_vector();
   105         ret = i;
   106         break;
   107       }
   108     }
   109 
   110     if (ret != threadVectors.size() - 1) {
   111       //We wait for other thread(s) to call this method too:
   112       printf("Thread %d wait\n", ret);
   113       pthread_cond_wait(&condition, &mutex);
   114     }
   115     else {
   116       //We are the last thread calling this method, we signal this
   117       //to the other thread(s) that might be waiting:
   118       printf("Thread %d signal\n", ret);
   119       pthread_cond_signal(&condition);
   120     }
   121 
   122     pthread_mutex_unlock(&mutex);
   123 
   124     return ret;
   125   }
   126 
   127   thread_vector& getThreadVector(size_t index) {
   128     //We return other thread thread_vector instance:
   129     return *threadVectors[(index + 1 == threadVectors.size()) ? 0 : index + 1];
   130   }
   131 
   132 private:
   133   pthread_mutex_t mutex;
   134   pthread_cond_t condition;
   135   vector<thread_vector*> threadVectors;
   136 };
   137 
   138 void* f(void* pdatas) {
   139   SharedDatas *psharedDatas = (SharedDatas*)pdatas;
   140 
   141   int threadIndex = psharedDatas->initThreadVector();
   142 
   143   for (int i = 0; i < 100; ++i) {
   144     psharedDatas->getThreadVector(threadIndex).push_back(i);
   145   }
   146 
   147   return 0;
   148 }
   149 
   150 void AllocatorTest::per_thread_alloc()
   151 {
   152   const size_t nth = 2;
   153   SharedDatas datas(nth);
   154   pthread_t t[nth];
   155 
   156   size_t i;
   157   for (i = 0; i < nth; ++i) {
   158     pthread_create(&t[i], 0, f, &datas);
   159   }
   160 
   161   for (i = 0; i < nth; ++i ) {
   162     pthread_join(t[i], 0);
   163   }
   164 }
   165 #endif