am c80353d7: am ca5d0d73: Enable clang compilation for mips.
[platform/upstream/VK-GL-CTS.git] / framework / delibs / decpp / deSharedPtr.cpp
1 /*-------------------------------------------------------------------------
2  * drawElements C++ Base Library
3  * -----------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Shared pointer.
22  *//*--------------------------------------------------------------------*/
23
24 #include "deSharedPtr.hpp"
25 #include "deThread.hpp"
26 #include "deClock.h"
27
28 #include <exception>
29
30 namespace de
31 {
32
33 namespace
34 {
35
36 enum
37 {
38         THREAD_TEST_TIME = 200*1000
39 };
40
41 class Object
42 {
43 public:
44         Object (bool& exists)
45                 : m_exists(exists)
46         {
47                 m_exists = true;
48         }
49
50         virtual ~Object (void)
51         {
52                 m_exists = false;
53         }
54
55 private:
56         bool& m_exists;
57 };
58
59 class DerivedObject : public Object
60 {
61 public:
62         DerivedObject (bool& exists)
63                 : Object(exists)
64         {
65         }
66 };
67
68 class SharedPtrTestThread : public Thread
69 {
70 public:
71         SharedPtrTestThread (const SharedPtr<Object>& ptr, const bool& exists)
72                 : m_ptr         (ptr)
73                 , m_exists      (exists)
74         {
75         }
76
77         void run (void)
78         {
79                 deUint64 startTime      = deGetMicroseconds();
80                 deUint64 cnt            = 0;
81
82                 for (;; cnt++)
83                 {
84                         if (((cnt&(1<<14)) != 0) && (deGetMicroseconds()-startTime >= THREAD_TEST_TIME))
85                                 break;
86
87                         {
88                                 SharedPtr<Object> ptrA(m_ptr);
89                                 {
90                                         SharedPtr<Object> ptrB;
91                                         ptrB = ptrA;
92                                         ptrA = SharedPtr<Object>();
93                                 }
94                         }
95                         DE_TEST_ASSERT(m_exists);
96                 }
97         }
98
99 private:
100         SharedPtr<Object>       m_ptr;
101         const bool&                     m_exists;
102 };
103
104 class WeakPtrTestThread : public Thread
105 {
106 public:
107         WeakPtrTestThread (const SharedPtr<Object>& ptr, const bool& exists)
108                 : m_ptr         (ptr)
109                 , m_exists      (exists)
110         {
111         }
112
113         void run (void)
114         {
115                 deUint64 startTime      = deGetMicroseconds();
116                 deUint64 cnt            = 0;
117
118                 for (;; cnt++)
119                 {
120                         if (((cnt&(1<<14)) != 0) && (deGetMicroseconds()-startTime >= THREAD_TEST_TIME))
121                                 break;
122
123                         {
124                                 WeakPtr<Object> ptrA(m_ptr);
125                                 {
126                                         WeakPtr<Object> ptrB;
127                                         ptrB = ptrA;
128                                         ptrA = SharedPtr<Object>();
129                                 }
130                         }
131                         DE_TEST_ASSERT(m_exists);
132                 }
133         }
134
135 private:
136         SharedPtr<Object>       m_ptr;
137         const bool&                     m_exists;
138 };
139
140 SharedPtr<Object> makeObject (bool& exists)
141 {
142         return SharedPtr<Object>(new Object(exists));
143 }
144
145 struct CustomDeleter
146 {
147         CustomDeleter (bool* called) : m_called(called) {}
148
149         void operator() (Object* ptr)
150         {
151                 DE_TEST_ASSERT(!*m_called);
152                 delete ptr;
153                 *m_called = true;
154         }
155
156         bool* m_called;
157 };
158
159 } // anonymous
160
161 void SharedPtr_selfTest (void)
162 {
163         // Empty pointer test.
164         {
165                 SharedPtr<Object> ptr;
166                 DE_TEST_ASSERT(ptr.get() == DE_NULL);
167                 DE_TEST_ASSERT(!ptr);
168         }
169
170         // Empty pointer copy.
171         {
172                 SharedPtr<Object> ptrA;
173                 SharedPtr<Object> ptrB(ptrA);
174                 DE_TEST_ASSERT(ptrB.get() == DE_NULL);
175         }
176
177         // Empty pointer assignment.
178         {
179                 SharedPtr<Object> ptrA;
180                 SharedPtr<Object> ptrB;
181                 ptrB = ptrA;
182                 ptrB = ptrB;
183         }
184
185         // Basic test.
186         {
187                 bool exists = false;
188                 {
189                         SharedPtr<Object> ptr(new Object(exists));
190                         DE_TEST_ASSERT(exists);
191                         DE_TEST_ASSERT(ptr.get() != DE_NULL);
192                         DE_TEST_ASSERT(ptr);
193                 }
194                 DE_TEST_ASSERT(!exists);
195         }
196
197         // Exception test.
198         {
199                 bool exists = false;
200                 try
201                 {
202                         SharedPtr<Object> ptr(new Object(exists));
203                         DE_TEST_ASSERT(exists);
204                         DE_TEST_ASSERT(ptr.get() != DE_NULL);
205                         throw std::exception();
206                 }
207                 catch (const std::exception&)
208                 {
209                         DE_TEST_ASSERT(!exists);
210                 }
211                 DE_TEST_ASSERT(!exists);
212         }
213
214         // Expression test.
215         {
216                 bool exists = false;
217                 bool test       = (SharedPtr<Object>(new Object(exists))).get() != DE_NULL && exists;
218                 DE_TEST_ASSERT(!exists);
219                 DE_TEST_ASSERT(test);
220         }
221
222         // Assignment test.
223         {
224                 bool exists = false;
225                 SharedPtr<Object> ptr(new Object(exists));
226                 DE_TEST_ASSERT(exists);
227                 ptr = SharedPtr<Object>();
228                 DE_TEST_ASSERT(!exists);
229         }
230
231         // Self-assignment test.
232         {
233                 bool exists = false;
234                 {
235                         SharedPtr<Object> ptr(new Object(exists));
236                         DE_TEST_ASSERT(exists);
237                         DE_TEST_ASSERT(ptr.get() != DE_NULL);
238                         ptr = ptr;
239                 }
240                 DE_TEST_ASSERT(!exists);
241         }
242
243         // Basic multi-reference via copy ctor.
244         {
245                 bool exists = false;
246                 {
247                         SharedPtr<Object> ptrA(new Object(exists));
248                         DE_TEST_ASSERT(exists);
249                         {
250                                 SharedPtr<Object> ptrB(ptrA);
251                                 DE_TEST_ASSERT(exists);
252                         }
253                         DE_TEST_ASSERT(exists);
254                 }
255                 DE_TEST_ASSERT(!exists);
256         }
257
258         // Basic multi-reference via assignment to empty.
259         {
260                 bool exists = false;
261                 {
262                         SharedPtr<Object> ptrA(new Object(exists));
263                         DE_TEST_ASSERT(exists);
264                         {
265                                 SharedPtr<Object> ptrB;
266                                 ptrB = ptrA;
267                                 DE_TEST_ASSERT(exists);
268                         }
269                         DE_TEST_ASSERT(exists);
270                 }
271                 DE_TEST_ASSERT(!exists);
272         }
273
274         // Multi-reference via assignment to non-empty.
275         {
276                 bool existsA = false;
277                 bool existsB = false;
278                 {
279                         SharedPtr<Object> ptrA(new Object(existsA));
280                         DE_TEST_ASSERT(existsA);
281                         {
282                                 SharedPtr<Object> ptrB(new Object(existsB));
283                                 DE_TEST_ASSERT(existsB);
284                                 ptrA = ptrB;
285                                 DE_TEST_ASSERT(!existsA);
286                                 DE_TEST_ASSERT(existsB);
287                         }
288                         DE_TEST_ASSERT(existsB);
289                 }
290                 DE_TEST_ASSERT(!existsB);
291         }
292
293         // Return from function.
294         {
295                 bool exists = false;
296                 {
297                         SharedPtr<Object> ptr;
298                         ptr = makeObject(exists);
299                         DE_TEST_ASSERT(exists);
300                 }
301                 DE_TEST_ASSERT(!exists);
302         }
303
304         // Equality comparison.
305         {
306                 bool existsA = false;
307                 bool existsB = false;
308                 SharedPtr<Object> ptrA(new Object(existsA));
309                 SharedPtr<Object> ptrB(new Object(existsB));
310                 SharedPtr<Object> ptrC(ptrA);
311
312                 DE_TEST_ASSERT(ptrA == ptrA);
313                 DE_TEST_ASSERT(ptrA != ptrB);
314                 DE_TEST_ASSERT(ptrA == ptrC);
315                 DE_TEST_ASSERT(ptrC != ptrB);
316         }
317
318         // Conversion via assignment.
319         {
320                 bool exists = false;
321                 {
322                         SharedPtr<Object> basePtr;
323                         {
324                                 SharedPtr<DerivedObject> derivedPtr(new DerivedObject(exists));
325                                 DE_TEST_ASSERT(exists);
326                                 basePtr = derivedPtr;
327                                 DE_TEST_ASSERT(exists);
328                         }
329                         DE_TEST_ASSERT(exists);
330                 }
331                 DE_TEST_ASSERT(!exists);
332         }
333
334         // Conversion via copy ctor.
335         {
336                 bool exists = false;
337                 {
338                         SharedPtr<DerivedObject>        derivedPtr      (new DerivedObject(exists));
339                         SharedPtr<Object>                       basePtr         (derivedPtr);
340                         DE_TEST_ASSERT(exists);
341                         derivedPtr = SharedPtr<DerivedObject>();
342                         DE_TEST_ASSERT(exists);
343                 }
344                 DE_TEST_ASSERT(!exists);
345         }
346
347         // Explicit conversion operator.
348         {
349                 bool exists = false;
350                 {
351                         SharedPtr<DerivedObject> derivedPtr (new DerivedObject(exists));
352                         DE_TEST_ASSERT(exists);
353
354                         SharedPtr<Object> basePtr = (SharedPtr<Object>)(derivedPtr);
355                         derivedPtr = SharedPtr<DerivedObject>();
356                         DE_TEST_ASSERT(exists);
357                 }
358                 DE_TEST_ASSERT(!exists);
359         }
360
361         // Basic weak reference.
362         {
363                 bool exists = false;
364                 SharedPtr<Object> ptr(new Object(exists));
365                 DE_TEST_ASSERT(exists);
366
367                 WeakPtr<Object> weakPtr(ptr);
368                 try
369                 {
370                         SharedPtr<Object> newRef(weakPtr);
371                         DE_TEST_ASSERT(exists);
372                 }
373                 catch (const DeadReferenceException&)
374                 {
375                         DE_TEST_ASSERT(false);
376                 }
377
378                 ptr = SharedPtr<Object>();
379                 DE_TEST_ASSERT(!exists);
380                 try
381                 {
382                         SharedPtr<Object> newRef(weakPtr);
383                         DE_TEST_ASSERT(false);
384                 }
385                 catch (const DeadReferenceException&)
386                 {
387                 }
388         }
389
390         // Basic SharedPtr threaded test.
391         {
392                 bool exists = false;
393                 {
394                         SharedPtr<Object> ptr(new Object(exists));
395
396                         SharedPtrTestThread threadA(ptr, exists);
397                         SharedPtrTestThread threadB(ptr, exists);
398
399                         threadA.start();
400                         threadB.start();
401
402                         threadA.join();
403                         threadB.join();
404                         DE_TEST_ASSERT(exists);
405                 }
406                 DE_TEST_ASSERT(!exists);
407         }
408
409         // Basic WeakPtr threaded test.
410         {
411                 bool exists = false;
412                 {
413                         SharedPtr<Object> ptr(new Object(exists));
414                         WeakPtrTestThread threadA(ptr, exists);
415                         WeakPtrTestThread threadB(ptr, exists);
416
417                         threadA.start();
418                         threadB.start();
419
420                         threadA.join();
421                         threadB.join();
422                         DE_TEST_ASSERT(exists);
423                 }
424                 DE_TEST_ASSERT(!exists);
425         }
426
427         // Basic custom deleter.
428         {
429                 bool exists = false;
430                 bool deleterCalled = false;
431                 {
432                         SharedPtr<Object> ptr(new Object(exists), CustomDeleter(&deleterCalled));
433                         DE_TEST_ASSERT(exists);
434                         DE_TEST_ASSERT(!deleterCalled);
435                         DE_TEST_ASSERT(ptr.get() != DE_NULL);
436                 }
437                 DE_TEST_ASSERT(!exists);
438                 DE_TEST_ASSERT(deleterCalled);
439         }
440 }
441
442 } // de