TestThreadSmartPtr.cpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Copyright (c) Electronic Arts Inc. All rights reserved.
  3. ///////////////////////////////////////////////////////////////////////////////
  4. #include "TestThread.h"
  5. #include <EATest/EATest.h>
  6. #include <eathread/eathread_thread.h>
  7. #include <eathread/shared_ptr_mt.h>
  8. #include <eathread/shared_array_mt.h>
  9. #include <eathread/eathread_atomic.h> // required to test the c11 atomics macros
  10. using namespace EA::Thread;
  11. struct TestClass
  12. {
  13. int x;
  14. };
  15. static bool IsTrue(bool b)
  16. {
  17. return b;
  18. }
  19. static bool IsFalse(bool b)
  20. {
  21. return !b;
  22. }
  23. namespace not_eastl
  24. {
  25. // Stub of std::shared_ptr implementation used to exercise the C11 atomic
  26. // macro expansion. This was causing issues because the function names of
  27. // the free standing eastl::shared_ptr functions and the C11 atomics
  28. // functions collided. Since the C11 atomics were implemented as macros we
  29. // can not utilize any scoping so we are forced to prevent the problem
  30. // polluting the global namespace.
  31. template <typename T> class shared_ptr { };
  32. template <typename T> inline bool atomic_is_lock_free(const shared_ptr<T>*) { return false; }
  33. template <typename T> inline shared_ptr<T> atomic_load(const shared_ptr<T>* pSharedPtr) { return *pSharedPtr; }
  34. template <typename T> inline shared_ptr<T> atomic_load_explicit(const shared_ptr<T>* pSharedPtr, ...) { return *pSharedPtr; }
  35. template <typename T> inline void atomic_store(shared_ptr<T>* pSharedPtrA, shared_ptr<T> sharedPtrB) {}
  36. template <typename T> inline void atomic_store_explicit(shared_ptr<T>* pSharedPtrA, shared_ptr<T> sharedPtrB, ...) {}
  37. template <typename T> shared_ptr<T> atomic_exchange(shared_ptr<T>* pSharedPtrA, shared_ptr<T> sharedPtrB) { return sharedPtrB; }
  38. template <typename T> inline shared_ptr<T> atomic_exchange_explicit(shared_ptr<T>* pSharedPtrA, shared_ptr<T> sharedPtrB, ...){ return *pSharedPtrA; }
  39. template <typename T> bool atomic_compare_exchange_strong(shared_ptr<T>* pSharedPtr, shared_ptr<T>* pSharedPtrCondition, shared_ptr<T> sharedPtrNew) { return false; }
  40. template <typename T> inline bool atomic_compare_exchange_weak(shared_ptr<T>* pSharedPtr, shared_ptr<T>* pSharedPtrCondition, shared_ptr<T> sharedPtrNew) { return false; }
  41. template <typename T> inline bool atomic_compare_exchange_strong_explicit(shared_ptr<T>* pSharedPtr, shared_ptr<T>* pSharedPtrCondition, shared_ptr<T> sharedPtrNew, ...) { return false; }
  42. template <typename T> inline bool atomic_compare_exchange_weak_explicit(shared_ptr<T>* pSharedPtr, shared_ptr<T>* pSharedPtrCondition, shared_ptr<T> sharedPtrNew, ...) { return false; }
  43. }
  44. int TestThreadSmartPtr()
  45. {
  46. int nErrorCount(0);
  47. // C11 atomics & eastl::shared_ptr name collision tests.
  48. {
  49. // If you are seeing compiler errors regarding C11 atomic macro
  50. // expansions here look at header file eathread_atomic_android_c11.h.
  51. // Ensure C11 atomic macros are being undefined properly. We hit this
  52. // problem on android-gcc config.
  53. using namespace not_eastl;
  54. shared_ptr<int> ptr1, ptr2, ptr3;
  55. atomic_is_lock_free(&ptr1);
  56. atomic_load(&ptr1);
  57. atomic_load_explicit(&ptr1);
  58. atomic_store(&ptr1, ptr2);
  59. atomic_store_explicit(&ptr1, ptr2);
  60. atomic_exchange(&ptr1, ptr2);
  61. atomic_exchange_explicit(&ptr1, ptr2);
  62. atomic_compare_exchange_strong(&ptr1, &ptr2, ptr3);
  63. atomic_compare_exchange_weak(&ptr1, &ptr2, ptr3);
  64. atomic_compare_exchange_strong_explicit(&ptr1, &ptr2, ptr3);
  65. atomic_compare_exchange_strong_explicit(&ptr1, &ptr2, ptr3);
  66. }
  67. { // Basic single-threaded test.
  68. typedef shared_ptr_mt<TestClass> TestClassSharedPtr;
  69. // typedef T element_type;
  70. EATEST_VERIFY_MSG(sizeof(TestClassSharedPtr::element_type) > 0, "shared_ptr_mt failure.");
  71. // typedef T value_type;
  72. EATEST_VERIFY_MSG(sizeof(TestClassSharedPtr::value_type) > 0, "shared_ptr_mt failure");
  73. // explicit shared_ptr_mt(T* pValue = 0)
  74. TestClassSharedPtr pSharedPtr0;
  75. TestClassSharedPtr pSharedPtr1(new TestClass);
  76. TestClassSharedPtr pSharedPtr2(new TestClass);
  77. // shared_ptr_mt(shared_ptr_mt const& sharedPtr)
  78. TestClassSharedPtr pSharedPtr3(pSharedPtr1);
  79. // void lock() const
  80. // void unlock() const
  81. pSharedPtr0.lock();
  82. pSharedPtr0.unlock();
  83. // operator bool_() const
  84. EATEST_VERIFY_MSG(IsFalse(pSharedPtr0), "shared_ptr_mt failure");
  85. EATEST_VERIFY_MSG( IsTrue(pSharedPtr1), "shared_ptr_mt failure");
  86. // bool operator!() const
  87. EATEST_VERIFY_MSG( IsTrue(!pSharedPtr0), "shared_ptr_mt failure");
  88. EATEST_VERIFY_MSG(IsFalse(!pSharedPtr1), "shared_ptr_mt failure");
  89. // int use_count() const
  90. EATEST_VERIFY_MSG(pSharedPtr0.use_count() == 1, "shared_ptr_mt failure");
  91. EATEST_VERIFY_MSG(pSharedPtr1.use_count() == 2, "shared_ptr_mt failure");
  92. EATEST_VERIFY_MSG(pSharedPtr2.use_count() == 1, "shared_ptr_mt failure");
  93. EATEST_VERIFY_MSG(pSharedPtr3.use_count() == 2, "shared_ptr_mt failure");
  94. // bool unique() const
  95. EATEST_VERIFY_MSG( pSharedPtr0.unique(), "shared_ptr_mt failure");
  96. EATEST_VERIFY_MSG(!pSharedPtr1.unique(), "shared_ptr_mt failure");
  97. EATEST_VERIFY_MSG( pSharedPtr2.unique(), "shared_ptr_mt failure");
  98. EATEST_VERIFY_MSG(!pSharedPtr3.unique(), "shared_ptr_mt failure");
  99. // shared_ptr_mt& operator=(shared_ptr_mt const& sharedPtr)
  100. pSharedPtr3 = pSharedPtr2;
  101. EATEST_VERIFY_MSG(pSharedPtr1.use_count() == 1, "shared_ptr_mt failure");
  102. EATEST_VERIFY_MSG(pSharedPtr2.use_count() == 2, "shared_ptr_mt failure");
  103. EATEST_VERIFY_MSG(pSharedPtr3.use_count() == 2, "shared_ptr_mt failure");
  104. // void reset(T* pValue = 0)
  105. pSharedPtr2.reset();
  106. EATEST_VERIFY_MSG(IsFalse(pSharedPtr2), "shared_ptr_mt failure");
  107. EATEST_VERIFY_MSG(pSharedPtr1.use_count() == 1, "shared_ptr_mt failure");
  108. EATEST_VERIFY_MSG(pSharedPtr2.use_count() == 1, "shared_ptr_mt failure");
  109. EATEST_VERIFY_MSG(pSharedPtr3.use_count() == 1, "shared_ptr_mt failure");
  110. pSharedPtr3.reset(new TestClass);
  111. EATEST_VERIFY_MSG(IsTrue(pSharedPtr3), "shared_ptr_mt failure");
  112. EATEST_VERIFY_MSG(pSharedPtr3.use_count() == 1, "shared_ptr_mt failure");
  113. // T* get() const
  114. TestClass* pA = pSharedPtr1.get();
  115. TestClass* pB = pSharedPtr3.get();
  116. // template<class T>
  117. // inline T* get_pointer(const shared_ptr_mt<T>& sharedPtr)
  118. EATEST_VERIFY_MSG(get_pointer(pSharedPtr1) == pA, "shared_ptr_mt failure");
  119. EATEST_VERIFY_MSG(get_pointer(pSharedPtr3) == pB, "shared_ptr_mt failure");
  120. // void swap(shared_ptr_mt<T>& sharedPtr)
  121. pSharedPtr1.swap(pSharedPtr3);
  122. EATEST_VERIFY_MSG(pSharedPtr1.get() == pB, "shared_ptr_mt failure");
  123. EATEST_VERIFY_MSG(pSharedPtr3.get() == pA, "shared_ptr_mt failure");
  124. // T& operator*() const
  125. (*pSharedPtr1).x = 37;
  126. EATEST_VERIFY_MSG(pSharedPtr1.get()->x == 37, "shared_ptr_mt failure");
  127. // T* operator->() const
  128. pSharedPtr1->x = 73;
  129. EATEST_VERIFY_MSG(pSharedPtr1.get()->x == 73, "shared_ptr_mt failure");
  130. // template<class T>
  131. // inline void swap(shared_ptr_mt<T>& sharedPtr1, shared_ptr_mt<T>& sharedPtr2)
  132. swap(pSharedPtr1, pSharedPtr2);
  133. EATEST_VERIFY_MSG(pSharedPtr2.get()->x == 73, "shared_ptr_mt failure");
  134. // template<class T, class U>
  135. // inline bool operator==(const shared_ptr_mt<T>& sharedPtr1, const shared_ptr_mt<U>& sharedPtr2)
  136. bool bEqual = pSharedPtr1 == pSharedPtr2;
  137. EATEST_VERIFY_MSG(!bEqual, "shared_ptr_mt failure");
  138. // template<class T, class U>
  139. // inline bool operator!=(const shared_ptr_mt<T>& sharedPtr1, const shared_ptr_mt<U>& sharedPtr2)
  140. bool bNotEqual = pSharedPtr1 != pSharedPtr2;
  141. EATEST_VERIFY_MSG(bNotEqual, "shared_ptr_mt failure");
  142. // template<class T, class U>
  143. // inline bool operator<(const shared_ptr_mt<T>& sharedPtr1, const shared_ptr_mt<U>& sharedPtr2)
  144. bool bLessA = pSharedPtr1 < pSharedPtr2;
  145. bool bLessB = pSharedPtr2 < pSharedPtr1;
  146. EATEST_VERIFY_MSG(bLessA || bLessB, "shared_ptr_mt failure");
  147. }
  148. {
  149. typedef shared_array_mt<TestClass> TestClassSharedArray;
  150. TestClassSharedArray pSharedArray(new TestClass[5]);
  151. TestClassSharedArray pSharedArray2(pSharedArray);
  152. // To do: Implement the tests above.
  153. }
  154. return nErrorCount;
  155. }