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