• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 //
zero_allocation()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 
bad_alloc_test()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     // Just it case it succeeds:
69     bigStructAlloc.deallocate(pbigStruct, 1024 * 1024 * 1024);
70   }
71   catch (bad_alloc const&) {
72   }
73   catch (...) {
74     //We shouldn't be there:
75     //Not bad_alloc exception thrown.
76     CPPUNIT_FAIL;
77   }
78 }
79 #endif
80 
81 #if defined (STLPORT) && defined (_STLP_THREADS) && defined (_STLP_USE_PERTHREAD_ALLOC)
82 #  include <pthread.h>
83 
84 class SharedDatas
85 {
86 public:
87   typedef vector<int, per_thread_allocator<int> > thread_vector;
88 
SharedDatas(size_t nbElems)89   SharedDatas(size_t nbElems) : threadVectors(nbElems, (thread_vector*)0) {
90     pthread_mutex_init(&mutex, 0);
91     pthread_cond_init(&condition, 0);
92   }
93 
~SharedDatas()94   ~SharedDatas() {
95     for (size_t i = 0; i < threadVectors.size(); ++i) {
96       delete threadVectors[i];
97     }
98   }
99 
initThreadVector()100   size_t initThreadVector() {
101     size_t ret;
102 
103     pthread_mutex_lock(&mutex);
104 
105     for (size_t i = 0; i < threadVectors.size(); ++i) {
106       if (threadVectors[i] == 0) {
107         threadVectors[i] = new thread_vector();
108         ret = i;
109         break;
110       }
111     }
112 
113     if (ret != threadVectors.size() - 1) {
114       //We wait for other thread(s) to call this method too:
115       printf("Thread %d wait\n", ret);
116       pthread_cond_wait(&condition, &mutex);
117     }
118     else {
119       //We are the last thread calling this method, we signal this
120       //to the other thread(s) that might be waiting:
121       printf("Thread %d signal\n", ret);
122       pthread_cond_signal(&condition);
123     }
124 
125     pthread_mutex_unlock(&mutex);
126 
127     return ret;
128   }
129 
getThreadVector(size_t index)130   thread_vector& getThreadVector(size_t index) {
131     //We return other thread thread_vector instance:
132     return *threadVectors[(index + 1 == threadVectors.size()) ? 0 : index + 1];
133   }
134 
135 private:
136   pthread_mutex_t mutex;
137   pthread_cond_t condition;
138   vector<thread_vector*> threadVectors;
139 };
140 
f(void * pdatas)141 void* f(void* pdatas) {
142   SharedDatas *psharedDatas = (SharedDatas*)pdatas;
143 
144   int threadIndex = psharedDatas->initThreadVector();
145 
146   for (int i = 0; i < 100; ++i) {
147     psharedDatas->getThreadVector(threadIndex).push_back(i);
148   }
149 
150   return 0;
151 }
152 
per_thread_alloc()153 void AllocatorTest::per_thread_alloc()
154 {
155   const size_t nth = 2;
156   SharedDatas datas(nth);
157   pthread_t t[nth];
158 
159   size_t i;
160   for (i = 0; i < nth; ++i) {
161     pthread_create(&t[i], 0, f, &datas);
162   }
163 
164   for (i = 0; i < nth; ++i ) {
165     pthread_join(t[i], 0);
166   }
167 }
168 #endif
169