Atomics.cpp 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. // Converted from libcxx's tests
  9. // https://github.com/llvm-mirror/libcxx/tree/7175a079211ec78c8232d9d55fa4c1f9eeae803d/test/AZStd/atomics/
  10. // convert assert -> EXPECT_TRUE
  11. // convert EXPECT_TRUE\((.+)\s*==\s*(.+)\); -> EXPECT_EQ($2, $1);
  12. // * Exception: gtest cannot deal with atomic<T>::operator==, nor can it print the value, so these stay as-is
  13. // convert std:: -> AZStd::
  14. // convert T -> TypeParam
  15. // remove constexpr
  16. #include "UserTypes.h"
  17. #include <AzCore/std/parallel/atomic.h>
  18. namespace UnitTest
  19. {
  20. class Atomics
  21. : public LeakDetectionFixture
  22. {
  23. };
  24. template <class A, class T>
  25. bool cmpxchg_weak_loop(A& atomic, T& expected, T desired)
  26. {
  27. for (int i = 0; i < 10; i++)
  28. {
  29. if (atomic.compare_exchange_weak(expected, desired) == true)
  30. {
  31. return true;
  32. }
  33. }
  34. return false;
  35. }
  36. template <class A, class T>
  37. bool cmpxchg_weak_loop(A& atomic, T& expected, T desired, AZStd::memory_order success, AZStd::memory_order failure)
  38. {
  39. for (int i = 0; i < 10; i++)
  40. {
  41. if (atomic.compare_exchange_weak(expected, desired, success, failure) == true)
  42. {
  43. return true;
  44. }
  45. }
  46. return false;
  47. }
  48. template <class A, class T>
  49. bool c_cmpxchg_weak_loop(A* atomic, T* expected, T desired)
  50. {
  51. for (int i = 0; i < 10; i++)
  52. {
  53. if (AZStd::atomic_compare_exchange_weak(atomic, expected, desired) == true)
  54. {
  55. return true;
  56. }
  57. }
  58. return false;
  59. }
  60. template <class A, class T>
  61. bool c_cmpxchg_weak_loop(A* atomic, T* expected, T desired, AZStd::memory_order success, AZStd::memory_order failure)
  62. {
  63. for (int i = 0; i < 10; i++)
  64. {
  65. if (AZStd::atomic_compare_exchange_weak_explicit(atomic, expected, desired, success, failure) == true)
  66. {
  67. return true;
  68. }
  69. }
  70. return false;
  71. }
  72. struct IntWrapper
  73. {
  74. int i;
  75. explicit IntWrapper(int d = 0) { i = d; }
  76. friend bool operator==(const IntWrapper& x, const IntWrapper& y)
  77. {
  78. return x.i == y.i;
  79. }
  80. };
  81. using AllAtomicTypes = ::testing::Types<
  82. char,
  83. unsigned char,
  84. short,
  85. unsigned short,
  86. int,
  87. unsigned int,
  88. long,
  89. unsigned long,
  90. long long,
  91. unsigned long long,
  92. wchar_t,
  93. int*,
  94. const int*
  95. >;
  96. using IntegralAtomicTypes = ::testing::Types<
  97. char,
  98. unsigned char,
  99. short,
  100. unsigned short,
  101. int,
  102. unsigned int,
  103. long,
  104. unsigned long,
  105. long long,
  106. unsigned long long,
  107. wchar_t
  108. >;
  109. using PointerAtomicTypes = ::testing::Types<
  110. int*,
  111. const int*
  112. >;
  113. template <class T>
  114. struct AtomicOps : public Atomics {};
  115. template <class T>
  116. struct AtomicOpsIntegral : public Atomics {};
  117. template <class T>
  118. struct AtomicOpsPointer : public Atomics {};
  119. TYPED_TEST_SUITE(AtomicOps, AllAtomicTypes);
  120. TYPED_TEST_SUITE(AtomicOpsIntegral, IntegralAtomicTypes);
  121. TYPED_TEST_SUITE(AtomicOpsPointer, PointerAtomicTypes);
  122. TYPED_TEST(AtomicOps, CompareExchangeStrong)
  123. {
  124. {
  125. typedef AZStd::atomic<TypeParam> A;
  126. A a;
  127. TypeParam t(TypeParam(1));
  128. AZStd::atomic_store(&a, t);
  129. EXPECT_TRUE(AZStd::atomic_compare_exchange_strong(&a, &t, TypeParam(2)));
  130. EXPECT_TRUE(TypeParam(2) == a);
  131. EXPECT_TRUE(TypeParam(1) == t);
  132. EXPECT_FALSE(AZStd::atomic_compare_exchange_strong(&a, &t, TypeParam(3)));
  133. EXPECT_TRUE(TypeParam(2) == a);
  134. EXPECT_TRUE(TypeParam(2) == t);
  135. }
  136. {
  137. typedef AZStd::atomic<TypeParam> A;
  138. volatile A a;
  139. TypeParam t(TypeParam(1));
  140. AZStd::atomic_store(&a, t);
  141. EXPECT_TRUE(AZStd::atomic_compare_exchange_strong(&a, &t, TypeParam(2)));
  142. EXPECT_TRUE(TypeParam(2) == a);
  143. EXPECT_TRUE(TypeParam(1) == t);
  144. EXPECT_FALSE(AZStd::atomic_compare_exchange_strong(&a, &t, TypeParam(3)));
  145. EXPECT_TRUE(TypeParam(2) == a);
  146. EXPECT_TRUE(TypeParam(2) == t);
  147. }
  148. }
  149. TYPED_TEST(AtomicOps, CompareExchangeStrongExplicit)
  150. {
  151. {
  152. typedef AZStd::atomic<TypeParam> A;
  153. A a;
  154. TypeParam t(TypeParam(1));
  155. AZStd::atomic_store(&a, t);
  156. EXPECT_TRUE(AZStd::atomic_compare_exchange_strong_explicit(&a, &t, TypeParam(2), AZStd::memory_order_seq_cst, AZStd::memory_order_seq_cst));
  157. EXPECT_TRUE(TypeParam(2) == a);
  158. EXPECT_TRUE(TypeParam(1) == t);
  159. EXPECT_FALSE(AZStd::atomic_compare_exchange_strong_explicit(&a, &t, TypeParam(3), AZStd::memory_order_seq_cst, AZStd::memory_order_seq_cst));
  160. EXPECT_TRUE(TypeParam(2) == a);
  161. EXPECT_TRUE(TypeParam(2) == t);
  162. }
  163. {
  164. typedef AZStd::atomic<TypeParam> A;
  165. volatile A a;
  166. TypeParam t(TypeParam(1));
  167. AZStd::atomic_store(&a, t);
  168. EXPECT_TRUE(AZStd::atomic_compare_exchange_strong_explicit(&a, &t, TypeParam(2), AZStd::memory_order_seq_cst, AZStd::memory_order_seq_cst));
  169. EXPECT_TRUE(TypeParam(2) == a);
  170. EXPECT_TRUE(TypeParam(1) == t);
  171. EXPECT_FALSE(AZStd::atomic_compare_exchange_strong_explicit(&a, &t, TypeParam(3), AZStd::memory_order_seq_cst, AZStd::memory_order_seq_cst));
  172. EXPECT_TRUE(TypeParam(2) == a);
  173. EXPECT_TRUE(TypeParam(2) == t);
  174. }
  175. }
  176. TYPED_TEST(AtomicOps, CompareExchangeWeak)
  177. {
  178. {
  179. typedef AZStd::atomic<TypeParam> A;
  180. A a;
  181. TypeParam t(TypeParam(1));
  182. AZStd::atomic_store(&a, t);
  183. EXPECT_TRUE(c_cmpxchg_weak_loop(&a, &t, TypeParam(2)));
  184. EXPECT_TRUE(TypeParam(2) == a);
  185. EXPECT_TRUE(TypeParam(1) == t);
  186. EXPECT_FALSE(AZStd::atomic_compare_exchange_weak(&a, &t, TypeParam(3)));
  187. EXPECT_TRUE(TypeParam(2) == a);
  188. EXPECT_TRUE(TypeParam(2) == t);
  189. }
  190. {
  191. typedef AZStd::atomic<TypeParam> A;
  192. volatile A a;
  193. TypeParam t(TypeParam(1));
  194. AZStd::atomic_store(&a, t);
  195. EXPECT_TRUE(c_cmpxchg_weak_loop(&a, &t, TypeParam(2)));
  196. EXPECT_TRUE(TypeParam(2) == a);
  197. EXPECT_TRUE(TypeParam(1) == t);
  198. EXPECT_FALSE(AZStd::atomic_compare_exchange_weak(&a, &t, TypeParam(3)));
  199. EXPECT_TRUE(TypeParam(2) == a);
  200. EXPECT_TRUE(TypeParam(2) == t);
  201. }
  202. }
  203. TYPED_TEST(AtomicOps, CompareExchangeWeakExplicit)
  204. {
  205. {
  206. typedef AZStd::atomic<TypeParam> A;
  207. A a;
  208. TypeParam t(TypeParam(1));
  209. AZStd::atomic_store(&a, t);
  210. EXPECT_TRUE(c_cmpxchg_weak_loop(&a, &t, TypeParam(2), AZStd::memory_order_seq_cst, AZStd::memory_order_seq_cst));
  211. EXPECT_TRUE(a == TypeParam(2));
  212. EXPECT_TRUE(t == TypeParam(1));
  213. EXPECT_FALSE(AZStd::atomic_compare_exchange_weak_explicit(&a, &t, TypeParam(3), AZStd::memory_order_seq_cst, AZStd::memory_order_seq_cst));
  214. EXPECT_TRUE(a == TypeParam(2));
  215. EXPECT_TRUE(t == TypeParam(2));
  216. }
  217. {
  218. typedef AZStd::atomic<TypeParam> A;
  219. volatile A a;
  220. TypeParam t(TypeParam(1));
  221. AZStd::atomic_store(&a, t);
  222. EXPECT_TRUE(c_cmpxchg_weak_loop(&a, &t, TypeParam(2), AZStd::memory_order_seq_cst, AZStd::memory_order_seq_cst));
  223. EXPECT_TRUE(a == TypeParam(2));
  224. EXPECT_TRUE(t == TypeParam(1));
  225. EXPECT_FALSE(AZStd::atomic_compare_exchange_weak_explicit(&a, &t, TypeParam(3), AZStd::memory_order_seq_cst, AZStd::memory_order_seq_cst));
  226. EXPECT_TRUE(a == TypeParam(2));
  227. EXPECT_TRUE(t == TypeParam(2));
  228. }
  229. }
  230. TYPED_TEST(AtomicOps, Exchange)
  231. {
  232. typedef AZStd::atomic<TypeParam> A;
  233. A t;
  234. AZStd::atomic_store(&t, TypeParam(1));
  235. EXPECT_TRUE(AZStd::atomic_exchange(&t, TypeParam(2)) == TypeParam(1));
  236. EXPECT_TRUE(t == TypeParam(2));
  237. volatile A vt;
  238. AZStd::atomic_store(&vt, TypeParam(3));
  239. EXPECT_TRUE(AZStd::atomic_exchange(&vt, TypeParam(4)) == TypeParam(3));
  240. EXPECT_TRUE(vt == TypeParam(4));
  241. }
  242. TYPED_TEST(AtomicOps, ExchangeExplicit)
  243. {
  244. typedef AZStd::atomic<TypeParam> A;
  245. A t;
  246. AZStd::atomic_store(&t, TypeParam(1));
  247. EXPECT_TRUE(AZStd::atomic_exchange_explicit(&t, TypeParam(2), AZStd::memory_order_seq_cst) == TypeParam(1));
  248. EXPECT_TRUE(t == TypeParam(2));
  249. volatile A vt;
  250. AZStd::atomic_store(&vt, TypeParam(3));
  251. EXPECT_TRUE(AZStd::atomic_exchange_explicit(&vt, TypeParam(4), AZStd::memory_order_seq_cst) == TypeParam(3));
  252. EXPECT_TRUE(vt == TypeParam(4));
  253. }
  254. TYPED_TEST(AtomicOpsIntegral, FetchAdd)
  255. {
  256. {
  257. typedef AZStd::atomic<TypeParam> A;
  258. A t;
  259. AZStd::atomic_store(&t, TypeParam(1));
  260. EXPECT_TRUE(AZStd::atomic_fetch_add(&t, TypeParam(2)) == TypeParam(1));
  261. EXPECT_TRUE(t == TypeParam(3));
  262. }
  263. {
  264. typedef AZStd::atomic<TypeParam> A;
  265. volatile A t;
  266. AZStd::atomic_store(&t, TypeParam(1));
  267. EXPECT_TRUE(AZStd::atomic_fetch_add(&t, TypeParam(2)) == TypeParam(1));
  268. EXPECT_TRUE(t == TypeParam(3));
  269. }
  270. }
  271. TYPED_TEST(AtomicOpsPointer, FetchAdd)
  272. {
  273. {
  274. typedef AZStd::atomic<TypeParam> A;
  275. typedef typename AZStd::remove_pointer<TypeParam>::type X;
  276. A t;
  277. AZStd::atomic_store(&t, TypeParam(1 * sizeof(X)));
  278. EXPECT_TRUE(AZStd::atomic_fetch_add(&t, 2) == TypeParam(1 * sizeof(X)));
  279. EXPECT_TRUE(t == TypeParam(3 * sizeof(X)));
  280. }
  281. {
  282. typedef AZStd::atomic<TypeParam> A;
  283. typedef typename AZStd::remove_pointer<TypeParam>::type X;
  284. volatile A t;
  285. AZStd::atomic_store(&t, TypeParam(1 * sizeof(X)));
  286. EXPECT_TRUE(AZStd::atomic_fetch_add(&t, 2) == TypeParam(1 * sizeof(X)));
  287. EXPECT_TRUE(t == TypeParam(3 * sizeof(X)));
  288. }
  289. }
  290. TYPED_TEST(AtomicOpsIntegral, FetchAddExplicit)
  291. {
  292. {
  293. typedef AZStd::atomic<TypeParam> A;
  294. A t;
  295. AZStd::atomic_store(&t, TypeParam(1));
  296. EXPECT_TRUE(AZStd::atomic_fetch_add_explicit(&t, TypeParam(2), AZStd::memory_order_seq_cst) == TypeParam(1));
  297. EXPECT_TRUE(t == TypeParam(3));
  298. }
  299. {
  300. typedef AZStd::atomic<TypeParam> A;
  301. volatile A t;
  302. AZStd::atomic_store(&t, TypeParam(1));
  303. EXPECT_TRUE(AZStd::atomic_fetch_add_explicit(&t, TypeParam(2), AZStd::memory_order_seq_cst) == TypeParam(1));
  304. EXPECT_TRUE(t == TypeParam(3));
  305. }
  306. }
  307. TYPED_TEST(AtomicOpsPointer, FetchAddExplicit)
  308. {
  309. {
  310. typedef AZStd::atomic<TypeParam> A;
  311. typedef typename AZStd::remove_pointer<TypeParam>::type X;
  312. A t;
  313. AZStd::atomic_store(&t, TypeParam(1 * sizeof(X)));
  314. EXPECT_TRUE(AZStd::atomic_fetch_add_explicit(&t, 2, AZStd::memory_order_seq_cst) == TypeParam(1 * sizeof(X)));
  315. EXPECT_TRUE(t == TypeParam(3 * sizeof(X)));
  316. }
  317. {
  318. typedef AZStd::atomic<TypeParam> A;
  319. typedef typename AZStd::remove_pointer<TypeParam>::type X;
  320. volatile A t;
  321. AZStd::atomic_store(&t, TypeParam(1 * sizeof(X)));
  322. EXPECT_TRUE(AZStd::atomic_fetch_add_explicit(&t, 2, AZStd::memory_order_seq_cst) == TypeParam(1 * sizeof(X)));
  323. EXPECT_TRUE(t == TypeParam(3 * sizeof(X)));
  324. }
  325. }
  326. TYPED_TEST(AtomicOpsIntegral, FetchAnd)
  327. {
  328. {
  329. typedef AZStd::atomic<TypeParam> A;
  330. A t;
  331. AZStd::atomic_store(&t, TypeParam(1));
  332. EXPECT_TRUE(AZStd::atomic_fetch_and(&t, TypeParam(2)) == TypeParam(1));
  333. EXPECT_TRUE(t == TypeParam(0));
  334. }
  335. {
  336. typedef AZStd::atomic<TypeParam> A;
  337. volatile A t;
  338. AZStd::atomic_store(&t, TypeParam(3));
  339. EXPECT_TRUE(AZStd::atomic_fetch_and(&t, TypeParam(2)) == TypeParam(3));
  340. EXPECT_TRUE(t == TypeParam(2));
  341. }
  342. }
  343. TYPED_TEST(AtomicOpsIntegral, FetchAndExplicit)
  344. {
  345. {
  346. typedef AZStd::atomic<TypeParam> A;
  347. A t;
  348. AZStd::atomic_store(&t, TypeParam(1));
  349. EXPECT_TRUE(AZStd::atomic_fetch_and_explicit(&t, TypeParam(2),
  350. AZStd::memory_order_seq_cst) == TypeParam(1));
  351. EXPECT_TRUE(t == TypeParam(0));
  352. }
  353. {
  354. typedef AZStd::atomic<TypeParam> A;
  355. volatile A t;
  356. AZStd::atomic_store(&t, TypeParam(3));
  357. EXPECT_TRUE(AZStd::atomic_fetch_and_explicit(&t, TypeParam(2),
  358. AZStd::memory_order_seq_cst) == TypeParam(3));
  359. EXPECT_TRUE(t == TypeParam(2));
  360. }
  361. }
  362. TYPED_TEST(AtomicOpsIntegral, FetchOr)
  363. {
  364. {
  365. typedef AZStd::atomic<TypeParam> A;
  366. A t;
  367. AZStd::atomic_store(&t, TypeParam(1));
  368. EXPECT_TRUE(AZStd::atomic_fetch_or(&t, TypeParam(2)) == TypeParam(1));
  369. EXPECT_TRUE(t == TypeParam(3));
  370. }
  371. {
  372. typedef AZStd::atomic<TypeParam> A;
  373. volatile A t;
  374. AZStd::atomic_store(&t, TypeParam(3));
  375. EXPECT_TRUE(AZStd::atomic_fetch_or(&t, TypeParam(2)) == TypeParam(3));
  376. EXPECT_TRUE(t == TypeParam(3));
  377. }
  378. }
  379. TYPED_TEST(AtomicOpsIntegral, FetchOrExplicit)
  380. {
  381. {
  382. typedef AZStd::atomic<TypeParam> A;
  383. A t;
  384. AZStd::atomic_store(&t, TypeParam(1));
  385. EXPECT_TRUE(AZStd::atomic_fetch_or_explicit(&t, TypeParam(2),
  386. AZStd::memory_order_seq_cst) == TypeParam(1));
  387. EXPECT_TRUE(t == TypeParam(3));
  388. }
  389. {
  390. typedef AZStd::atomic<TypeParam> A;
  391. volatile A t;
  392. AZStd::atomic_store(&t, TypeParam(3));
  393. EXPECT_TRUE(AZStd::atomic_fetch_or_explicit(&t, TypeParam(2),
  394. AZStd::memory_order_seq_cst) == TypeParam(3));
  395. EXPECT_TRUE(t == TypeParam(3));
  396. }
  397. }
  398. TYPED_TEST(AtomicOpsIntegral, FetchSub)
  399. {
  400. {
  401. typedef AZStd::atomic<TypeParam> A;
  402. A t;
  403. AZStd::atomic_store(&t, TypeParam(3));
  404. EXPECT_TRUE(AZStd::atomic_fetch_sub(&t, TypeParam(2)) == TypeParam(3));
  405. EXPECT_TRUE(t == TypeParam(1));
  406. }
  407. {
  408. typedef AZStd::atomic<TypeParam> A;
  409. volatile A t;
  410. AZStd::atomic_store(&t, TypeParam(3));
  411. EXPECT_TRUE(AZStd::atomic_fetch_sub(&t, TypeParam(2)) == TypeParam(3));
  412. EXPECT_TRUE(t == TypeParam(1));
  413. }
  414. }
  415. TYPED_TEST(AtomicOpsIntegral, FetchSubExplicit)
  416. {
  417. {
  418. typedef AZStd::atomic<TypeParam> A;
  419. A t;
  420. AZStd::atomic_store(&t, TypeParam(3));
  421. EXPECT_TRUE(AZStd::atomic_fetch_sub_explicit(&t, TypeParam(2),
  422. AZStd::memory_order_seq_cst) == TypeParam(3));
  423. EXPECT_TRUE(t == TypeParam(1));
  424. }
  425. {
  426. typedef AZStd::atomic<TypeParam> A;
  427. volatile A t;
  428. AZStd::atomic_store(&t, TypeParam(3));
  429. EXPECT_TRUE(AZStd::atomic_fetch_sub_explicit(&t, TypeParam(2),
  430. AZStd::memory_order_seq_cst) == TypeParam(3));
  431. EXPECT_TRUE(t == TypeParam(1));
  432. }
  433. }
  434. TYPED_TEST(AtomicOpsIntegral, FetchXor)
  435. {
  436. {
  437. typedef AZStd::atomic<TypeParam> A;
  438. A t;
  439. AZStd::atomic_store(&t, TypeParam(1));
  440. EXPECT_TRUE(AZStd::atomic_fetch_xor(&t, TypeParam(2)) == TypeParam(1));
  441. EXPECT_TRUE(t == TypeParam(3));
  442. }
  443. {
  444. typedef AZStd::atomic<TypeParam> A;
  445. volatile A t;
  446. AZStd::atomic_store(&t, TypeParam(3));
  447. EXPECT_TRUE(AZStd::atomic_fetch_xor(&t, TypeParam(2)) == TypeParam(3));
  448. EXPECT_TRUE(t == TypeParam(1));
  449. }
  450. }
  451. TYPED_TEST(AtomicOpsIntegral, FetchXorExplicit)
  452. {
  453. {
  454. typedef AZStd::atomic<TypeParam> A;
  455. A t;
  456. AZStd::atomic_store(&t, TypeParam(1));
  457. EXPECT_TRUE(AZStd::atomic_fetch_xor_explicit(&t, TypeParam(2),
  458. AZStd::memory_order_seq_cst) == TypeParam(1));
  459. EXPECT_TRUE(t == TypeParam(3));
  460. }
  461. {
  462. typedef AZStd::atomic<TypeParam> A;
  463. volatile A t;
  464. AZStd::atomic_store(&t, TypeParam(3));
  465. EXPECT_TRUE(AZStd::atomic_fetch_xor_explicit(&t, TypeParam(2),
  466. AZStd::memory_order_seq_cst) == TypeParam(3));
  467. EXPECT_TRUE(t == TypeParam(1));
  468. }
  469. }
  470. TYPED_TEST(AtomicOps, Init)
  471. {
  472. typedef AZStd::atomic<TypeParam> A;
  473. A t;
  474. AZStd::atomic_store(&t, TypeParam(1));
  475. EXPECT_TRUE(t == TypeParam(1));
  476. volatile A vt;
  477. AZStd::atomic_store(&vt, TypeParam(2));
  478. EXPECT_TRUE(vt == TypeParam(2));
  479. }
  480. TYPED_TEST(AtomicOps, IsLockFree)
  481. {
  482. typedef AZStd::atomic<TypeParam> A;
  483. A t;
  484. bool b1 = AZStd::atomic_is_lock_free(static_cast<const A*>(&t));
  485. volatile A vt;
  486. bool b2 = AZStd::atomic_is_lock_free(static_cast<const volatile A*>(&vt));
  487. EXPECT_TRUE(b1 == b2);
  488. }
  489. TYPED_TEST(AtomicOps, Load)
  490. {
  491. typedef AZStd::atomic<TypeParam> A;
  492. A t;
  493. AZStd::atomic_store(&t, TypeParam(1));
  494. EXPECT_TRUE(AZStd::atomic_load(&t) == TypeParam(1));
  495. volatile A vt;
  496. AZStd::atomic_store(&vt, TypeParam(2));
  497. EXPECT_TRUE(AZStd::atomic_load(&vt) == TypeParam(2));
  498. }
  499. TYPED_TEST(AtomicOps, LoadExplicit)
  500. {
  501. typedef AZStd::atomic<TypeParam> A;
  502. A t;
  503. AZStd::atomic_store(&t, TypeParam(1));
  504. EXPECT_TRUE(AZStd::atomic_load_explicit(&t, AZStd::memory_order_seq_cst) == TypeParam(1));
  505. volatile A vt;
  506. AZStd::atomic_store(&vt, TypeParam(2));
  507. EXPECT_TRUE(AZStd::atomic_load_explicit(&vt, AZStd::memory_order_seq_cst) == TypeParam(2));
  508. }
  509. TYPED_TEST(AtomicOps, Store)
  510. {
  511. typedef AZStd::atomic<TypeParam> A;
  512. A t;
  513. AZStd::atomic_store(&t, TypeParam(1));
  514. EXPECT_TRUE(t == TypeParam(1));
  515. volatile A vt;
  516. AZStd::atomic_store(&vt, TypeParam(2));
  517. EXPECT_TRUE(vt == TypeParam(2));
  518. }
  519. TYPED_TEST(AtomicOps, StoreExplicit)
  520. {
  521. typedef AZStd::atomic<TypeParam> A;
  522. A t;
  523. AZStd::atomic_store_explicit(&t, TypeParam(1), AZStd::memory_order_seq_cst);
  524. EXPECT_TRUE(t == TypeParam(1));
  525. volatile A vt;
  526. AZStd::atomic_store_explicit(&vt, TypeParam(2), AZStd::memory_order_seq_cst);
  527. EXPECT_TRUE(vt == TypeParam(2));
  528. }
  529. template <class Tp>
  530. void test_ctor() {
  531. typedef AZStd::atomic<Tp> Atomic;
  532. Tp t(42);
  533. {
  534. Atomic a(t);
  535. EXPECT_TRUE(a == t);
  536. }
  537. {
  538. Atomic a{ t };
  539. EXPECT_TRUE(a == t);
  540. }
  541. {
  542. Atomic a = t;
  543. EXPECT_TRUE(a == t);
  544. }
  545. }
  546. TEST_F(Atomics, IntegralCtor)
  547. {
  548. test_ctor<int>();
  549. }
  550. TEST_F(Atomics, UserCtor)
  551. {
  552. test_ctor<IntWrapper>();
  553. }
  554. TEST_F(Atomics, SignalFence)
  555. {
  556. AZStd::atomic_signal_fence(AZStd::memory_order_seq_cst);
  557. }
  558. TEST_F(Atomics, ThreadFence)
  559. {
  560. AZStd::atomic_thread_fence(AZStd::memory_order_seq_cst);
  561. }
  562. TEST_F(Atomics, AtomicFlagClear)
  563. {
  564. {
  565. AZStd::atomic_flag f = AZ_ATOMIC_FLAG_INIT;
  566. f.test_and_set();
  567. atomic_flag_clear(&f);
  568. EXPECT_TRUE(f.test_and_set() == 0);
  569. }
  570. {
  571. volatile AZStd::atomic_flag f = AZ_ATOMIC_FLAG_INIT;
  572. f.test_and_set();
  573. atomic_flag_clear(&f);
  574. EXPECT_TRUE(f.test_and_set() == 0);
  575. }
  576. }
  577. TEST_F(Atomics, AtomicFlagClearExplicit)
  578. {
  579. {
  580. AZStd::atomic_flag f = AZ_ATOMIC_FLAG_INIT;
  581. f.test_and_set();
  582. atomic_flag_clear_explicit(&f, AZStd::memory_order_relaxed);
  583. EXPECT_TRUE(f.test_and_set() == 0);
  584. }
  585. {
  586. AZStd::atomic_flag f = AZ_ATOMIC_FLAG_INIT;
  587. f.test_and_set();
  588. atomic_flag_clear_explicit(&f, AZStd::memory_order_release);
  589. EXPECT_TRUE(f.test_and_set() == 0);
  590. }
  591. {
  592. AZStd::atomic_flag f = AZ_ATOMIC_FLAG_INIT;
  593. f.test_and_set();
  594. atomic_flag_clear_explicit(&f, AZStd::memory_order_seq_cst);
  595. EXPECT_TRUE(f.test_and_set() == 0);
  596. }
  597. {
  598. volatile AZStd::atomic_flag f = AZ_ATOMIC_FLAG_INIT;
  599. f.test_and_set();
  600. atomic_flag_clear_explicit(&f, AZStd::memory_order_relaxed);
  601. EXPECT_TRUE(f.test_and_set() == 0);
  602. }
  603. {
  604. volatile AZStd::atomic_flag f = AZ_ATOMIC_FLAG_INIT;
  605. f.test_and_set();
  606. atomic_flag_clear_explicit(&f, AZStd::memory_order_release);
  607. EXPECT_TRUE(f.test_and_set() == 0);
  608. }
  609. {
  610. volatile AZStd::atomic_flag f = AZ_ATOMIC_FLAG_INIT;
  611. f.test_and_set();
  612. atomic_flag_clear_explicit(&f, AZStd::memory_order_seq_cst);
  613. EXPECT_TRUE(f.test_and_set() == 0);
  614. }
  615. }
  616. TEST_F(Atomics, AtomicFlagTestAndSet)
  617. {
  618. {
  619. AZStd::atomic_flag f;
  620. f.clear();
  621. EXPECT_TRUE(atomic_flag_test_and_set(&f) == 0);
  622. EXPECT_TRUE(f.test_and_set() == 1);
  623. }
  624. {
  625. volatile AZStd::atomic_flag f;
  626. f.clear();
  627. EXPECT_TRUE(atomic_flag_test_and_set(&f) == 0);
  628. EXPECT_TRUE(f.test_and_set() == 1);
  629. }
  630. }
  631. TEST_F(Atomics, AtomicFlagTestAndSetExplicit)
  632. {
  633. {
  634. AZStd::atomic_flag f;
  635. f.clear();
  636. EXPECT_TRUE(atomic_flag_test_and_set_explicit(&f, AZStd::memory_order_relaxed) == 0);
  637. EXPECT_TRUE(f.test_and_set() == 1);
  638. }
  639. {
  640. AZStd::atomic_flag f;
  641. f.clear();
  642. EXPECT_TRUE(atomic_flag_test_and_set_explicit(&f, AZStd::memory_order_consume) == 0);
  643. EXPECT_TRUE(f.test_and_set() == 1);
  644. }
  645. {
  646. AZStd::atomic_flag f;
  647. f.clear();
  648. EXPECT_TRUE(atomic_flag_test_and_set_explicit(&f, AZStd::memory_order_acquire) == 0);
  649. EXPECT_TRUE(f.test_and_set() == 1);
  650. }
  651. {
  652. AZStd::atomic_flag f;
  653. f.clear();
  654. EXPECT_TRUE(atomic_flag_test_and_set_explicit(&f, AZStd::memory_order_release) == 0);
  655. EXPECT_TRUE(f.test_and_set() == 1);
  656. }
  657. {
  658. AZStd::atomic_flag f;
  659. f.clear();
  660. EXPECT_TRUE(atomic_flag_test_and_set_explicit(&f, AZStd::memory_order_acq_rel) == 0);
  661. EXPECT_TRUE(f.test_and_set() == 1);
  662. }
  663. {
  664. AZStd::atomic_flag f;
  665. f.clear();
  666. EXPECT_TRUE(atomic_flag_test_and_set_explicit(&f, AZStd::memory_order_seq_cst) == 0);
  667. EXPECT_TRUE(f.test_and_set() == 1);
  668. }
  669. {
  670. volatile AZStd::atomic_flag f;
  671. f.clear();
  672. EXPECT_TRUE(atomic_flag_test_and_set_explicit(&f, AZStd::memory_order_relaxed) == 0);
  673. EXPECT_TRUE(f.test_and_set() == 1);
  674. }
  675. {
  676. volatile AZStd::atomic_flag f;
  677. f.clear();
  678. EXPECT_TRUE(atomic_flag_test_and_set_explicit(&f, AZStd::memory_order_consume) == 0);
  679. EXPECT_TRUE(f.test_and_set() == 1);
  680. }
  681. {
  682. volatile AZStd::atomic_flag f;
  683. f.clear();
  684. EXPECT_TRUE(atomic_flag_test_and_set_explicit(&f, AZStd::memory_order_acquire) == 0);
  685. EXPECT_TRUE(f.test_and_set() == 1);
  686. }
  687. {
  688. volatile AZStd::atomic_flag f;
  689. f.clear();
  690. EXPECT_TRUE(atomic_flag_test_and_set_explicit(&f, AZStd::memory_order_release) == 0);
  691. EXPECT_TRUE(f.test_and_set() == 1);
  692. }
  693. {
  694. volatile AZStd::atomic_flag f;
  695. f.clear();
  696. EXPECT_TRUE(atomic_flag_test_and_set_explicit(&f, AZStd::memory_order_acq_rel) == 0);
  697. EXPECT_TRUE(f.test_and_set() == 1);
  698. }
  699. {
  700. volatile AZStd::atomic_flag f;
  701. f.clear();
  702. EXPECT_TRUE(atomic_flag_test_and_set_explicit(&f, AZStd::memory_order_seq_cst) == 0);
  703. EXPECT_TRUE(f.test_and_set() == 1);
  704. }
  705. }
  706. TEST_F(Atomics, AtomicFlagClearCombinations)
  707. {
  708. {
  709. AZStd::atomic_flag f = AZ_ATOMIC_FLAG_INIT;
  710. f.test_and_set();
  711. f.clear();
  712. EXPECT_TRUE(f.test_and_set() == 0);
  713. }
  714. {
  715. AZStd::atomic_flag f = AZ_ATOMIC_FLAG_INIT;
  716. f.test_and_set();
  717. f.clear(AZStd::memory_order_relaxed);
  718. EXPECT_TRUE(f.test_and_set() == 0);
  719. }
  720. {
  721. AZStd::atomic_flag f = AZ_ATOMIC_FLAG_INIT;
  722. f.test_and_set();
  723. f.clear(AZStd::memory_order_release);
  724. EXPECT_TRUE(f.test_and_set() == 0);
  725. }
  726. {
  727. AZStd::atomic_flag f = AZ_ATOMIC_FLAG_INIT;
  728. f.test_and_set();
  729. f.clear(AZStd::memory_order_seq_cst);
  730. EXPECT_TRUE(f.test_and_set() == 0);
  731. }
  732. {
  733. volatile AZStd::atomic_flag f = AZ_ATOMIC_FLAG_INIT;
  734. f.test_and_set();
  735. f.clear();
  736. EXPECT_TRUE(f.test_and_set() == 0);
  737. }
  738. {
  739. volatile AZStd::atomic_flag f = AZ_ATOMIC_FLAG_INIT;
  740. f.test_and_set();
  741. f.clear(AZStd::memory_order_relaxed);
  742. EXPECT_TRUE(f.test_and_set() == 0);
  743. }
  744. {
  745. volatile AZStd::atomic_flag f = AZ_ATOMIC_FLAG_INIT;
  746. f.test_and_set();
  747. f.clear(AZStd::memory_order_release);
  748. EXPECT_TRUE(f.test_and_set() == 0);
  749. }
  750. {
  751. volatile AZStd::atomic_flag f = AZ_ATOMIC_FLAG_INIT;
  752. f.test_and_set();
  753. f.clear(AZStd::memory_order_seq_cst);
  754. EXPECT_TRUE(f.test_and_set() == 0);
  755. }
  756. }
  757. TEST_F(Atomics, AtomicFlagDefault)
  758. {
  759. AZStd::atomic_flag f;
  760. f.clear();
  761. EXPECT_TRUE(f.test_and_set() == 0);
  762. {
  763. typedef AZStd::atomic_flag A;
  764. alignas(A) char storage[sizeof(A)] = { 1 };
  765. A& zero = *new (storage) A();
  766. EXPECT_TRUE(!zero.test_and_set());
  767. zero.~A();
  768. }
  769. }
  770. TEST_F(Atomics, AtomicFlagInit)
  771. {
  772. AZStd::atomic_flag f = AZ_ATOMIC_FLAG_INIT;
  773. EXPECT_TRUE(f.test_and_set() == 0);
  774. }
  775. TEST_F(Atomics, AtomicFlagTestAndSetCombinations)
  776. {
  777. {
  778. AZStd::atomic_flag f;
  779. f.clear();
  780. EXPECT_TRUE(f.test_and_set() == 0);
  781. EXPECT_TRUE(f.test_and_set() == 1);
  782. }
  783. {
  784. AZStd::atomic_flag f;
  785. f.clear();
  786. EXPECT_TRUE(f.test_and_set(AZStd::memory_order_relaxed) == 0);
  787. EXPECT_TRUE(f.test_and_set(AZStd::memory_order_relaxed) == 1);
  788. }
  789. {
  790. AZStd::atomic_flag f;
  791. f.clear();
  792. EXPECT_TRUE(f.test_and_set(AZStd::memory_order_consume) == 0);
  793. EXPECT_TRUE(f.test_and_set(AZStd::memory_order_consume) == 1);
  794. }
  795. {
  796. AZStd::atomic_flag f;
  797. f.clear();
  798. EXPECT_TRUE(f.test_and_set(AZStd::memory_order_acquire) == 0);
  799. EXPECT_TRUE(f.test_and_set(AZStd::memory_order_acquire) == 1);
  800. }
  801. {
  802. AZStd::atomic_flag f;
  803. f.clear();
  804. EXPECT_TRUE(f.test_and_set(AZStd::memory_order_release) == 0);
  805. EXPECT_TRUE(f.test_and_set(AZStd::memory_order_release) == 1);
  806. }
  807. {
  808. AZStd::atomic_flag f;
  809. f.clear();
  810. EXPECT_TRUE(f.test_and_set(AZStd::memory_order_acq_rel) == 0);
  811. EXPECT_TRUE(f.test_and_set(AZStd::memory_order_acq_rel) == 1);
  812. }
  813. {
  814. AZStd::atomic_flag f;
  815. f.clear();
  816. EXPECT_TRUE(f.test_and_set(AZStd::memory_order_seq_cst) == 0);
  817. EXPECT_TRUE(f.test_and_set(AZStd::memory_order_seq_cst) == 1);
  818. }
  819. {
  820. volatile AZStd::atomic_flag f;
  821. f.clear();
  822. EXPECT_TRUE(f.test_and_set() == 0);
  823. EXPECT_TRUE(f.test_and_set() == 1);
  824. }
  825. {
  826. volatile AZStd::atomic_flag f;
  827. f.clear();
  828. EXPECT_TRUE(f.test_and_set(AZStd::memory_order_relaxed) == 0);
  829. EXPECT_TRUE(f.test_and_set(AZStd::memory_order_relaxed) == 1);
  830. }
  831. {
  832. volatile AZStd::atomic_flag f;
  833. f.clear();
  834. EXPECT_TRUE(f.test_and_set(AZStd::memory_order_consume) == 0);
  835. EXPECT_TRUE(f.test_and_set(AZStd::memory_order_consume) == 1);
  836. }
  837. {
  838. volatile AZStd::atomic_flag f;
  839. f.clear();
  840. EXPECT_TRUE(f.test_and_set(AZStd::memory_order_acquire) == 0);
  841. EXPECT_TRUE(f.test_and_set(AZStd::memory_order_acquire) == 1);
  842. }
  843. {
  844. volatile AZStd::atomic_flag f;
  845. f.clear();
  846. EXPECT_TRUE(f.test_and_set(AZStd::memory_order_release) == 0);
  847. EXPECT_TRUE(f.test_and_set(AZStd::memory_order_release) == 1);
  848. }
  849. {
  850. volatile AZStd::atomic_flag f;
  851. f.clear();
  852. EXPECT_TRUE(f.test_and_set(AZStd::memory_order_acq_rel) == 0);
  853. EXPECT_TRUE(f.test_and_set(AZStd::memory_order_acq_rel) == 1);
  854. }
  855. {
  856. volatile AZStd::atomic_flag f;
  857. f.clear();
  858. EXPECT_TRUE(f.test_and_set(AZStd::memory_order_seq_cst) == 0);
  859. EXPECT_TRUE(f.test_and_set(AZStd::memory_order_seq_cst) == 1);
  860. }
  861. }
  862. TEST_F(Atomics, ValidateLockFreeMacros)
  863. {
  864. EXPECT_TRUE(AZ_ATOMIC_CHAR_LOCK_FREE == 0 ||
  865. AZ_ATOMIC_CHAR_LOCK_FREE == 1 ||
  866. AZ_ATOMIC_CHAR_LOCK_FREE == 2);
  867. EXPECT_TRUE(AZ_ATOMIC_CHAR16_T_LOCK_FREE == 0 ||
  868. AZ_ATOMIC_CHAR16_T_LOCK_FREE == 1 ||
  869. AZ_ATOMIC_CHAR16_T_LOCK_FREE == 2);
  870. EXPECT_TRUE(AZ_ATOMIC_CHAR32_T_LOCK_FREE == 0 ||
  871. AZ_ATOMIC_CHAR32_T_LOCK_FREE == 1 ||
  872. AZ_ATOMIC_CHAR32_T_LOCK_FREE == 2);
  873. EXPECT_TRUE(AZ_ATOMIC_WCHAR_T_LOCK_FREE == 0 ||
  874. AZ_ATOMIC_WCHAR_T_LOCK_FREE == 1 ||
  875. AZ_ATOMIC_WCHAR_T_LOCK_FREE == 2);
  876. EXPECT_TRUE(AZ_ATOMIC_SHORT_LOCK_FREE == 0 ||
  877. AZ_ATOMIC_SHORT_LOCK_FREE == 1 ||
  878. AZ_ATOMIC_SHORT_LOCK_FREE == 2);
  879. EXPECT_TRUE(AZ_ATOMIC_INT_LOCK_FREE == 0 ||
  880. AZ_ATOMIC_INT_LOCK_FREE == 1 ||
  881. AZ_ATOMIC_INT_LOCK_FREE == 2);
  882. EXPECT_TRUE(AZ_ATOMIC_LONG_LOCK_FREE == 0 ||
  883. AZ_ATOMIC_LONG_LOCK_FREE == 1 ||
  884. AZ_ATOMIC_LONG_LOCK_FREE == 2);
  885. EXPECT_TRUE(AZ_ATOMIC_LLONG_LOCK_FREE == 0 ||
  886. AZ_ATOMIC_LLONG_LOCK_FREE == 1 ||
  887. AZ_ATOMIC_LLONG_LOCK_FREE == 2);
  888. }
  889. TEST_F(Atomics, KillDependency)
  890. {
  891. EXPECT_TRUE(AZStd::kill_dependency(5) == 5);
  892. EXPECT_TRUE(AZStd::kill_dependency(-5.5) == -5.5);
  893. }
  894. TEST_F(Atomics, ValidateMemoryOrder)
  895. {
  896. EXPECT_TRUE(AZStd::to_underlying(AZStd::memory_order_relaxed) == 0);
  897. EXPECT_TRUE(AZStd::to_underlying(AZStd::memory_order_consume) == 1);
  898. EXPECT_TRUE(AZStd::to_underlying(AZStd::memory_order_acquire) == 2);
  899. EXPECT_TRUE(AZStd::to_underlying(AZStd::memory_order_release) == 3);
  900. EXPECT_TRUE(AZStd::to_underlying(AZStd::memory_order_acq_rel) == 4);
  901. EXPECT_TRUE(AZStd::to_underlying(AZStd::memory_order_seq_cst) == 5);
  902. AZStd::memory_order o = AZStd::memory_order_seq_cst;
  903. EXPECT_TRUE(AZStd::to_underlying(o) == 5);
  904. }
  905. template <class A, class T>
  906. void validate_atomic_ptr()
  907. {
  908. typedef typename AZStd::remove_pointer<T>::type X;
  909. A obj(T(0));
  910. bool b0 = obj.is_lock_free();
  911. ((void)b0); // mark as unused
  912. EXPECT_TRUE(obj == T(nullptr));
  913. AZStd::atomic_store(&obj, T(1));
  914. EXPECT_TRUE(obj == T(1));
  915. AZStd::atomic_store(&obj, T(2));
  916. EXPECT_TRUE(obj == T(2));
  917. obj.store(T(0));
  918. EXPECT_TRUE(obj == T(nullptr));
  919. obj.store(T(1), AZStd::memory_order_release);
  920. EXPECT_TRUE(obj == T(1));
  921. EXPECT_TRUE(obj.load() == T(1));
  922. EXPECT_TRUE(obj.load(AZStd::memory_order_acquire) == T(1));
  923. EXPECT_TRUE(obj.exchange(T(2)) == T(1));
  924. EXPECT_TRUE(obj == T(2));
  925. EXPECT_TRUE(obj.exchange(T(3), AZStd::memory_order_relaxed) == T(2));
  926. EXPECT_TRUE(obj == T(3));
  927. T x = obj;
  928. EXPECT_TRUE(cmpxchg_weak_loop(obj, x, T(2)) == true);
  929. EXPECT_TRUE(obj == T(2));
  930. EXPECT_TRUE(x == T(3));
  931. EXPECT_TRUE(obj.compare_exchange_weak(x, T(1)) == false);
  932. EXPECT_TRUE(obj == T(2));
  933. EXPECT_TRUE(x == T(2));
  934. x = T(2);
  935. EXPECT_TRUE(obj.compare_exchange_strong(x, T(1)) == true);
  936. EXPECT_TRUE(obj == T(1));
  937. EXPECT_TRUE(x == T(2));
  938. EXPECT_TRUE(obj.compare_exchange_strong(x, T(nullptr)) == false);
  939. EXPECT_TRUE(obj == T(1));
  940. EXPECT_TRUE(x == T(1));
  941. EXPECT_TRUE((obj = T(nullptr)) == T(nullptr));
  942. EXPECT_TRUE(obj == T(nullptr));
  943. obj = T(2 * sizeof(X));
  944. EXPECT_TRUE((obj += AZStd::ptrdiff_t(3)) == T(5 * sizeof(X)));
  945. EXPECT_TRUE(obj == T(5 * sizeof(X)));
  946. EXPECT_TRUE((obj -= AZStd::ptrdiff_t(3)) == T(2 * sizeof(X)));
  947. EXPECT_TRUE(obj == T(2 * sizeof(X)));
  948. {
  949. alignas(A) char storage[sizeof(A)] = { 23 };
  950. A& zero = *new (storage) A();
  951. EXPECT_TRUE(zero == T(nullptr));
  952. zero.~A();
  953. }
  954. }
  955. template <class A, class T>
  956. void validate_atomic_ptr_variations()
  957. {
  958. validate_atomic_ptr<A, T>();
  959. validate_atomic_ptr<volatile A, T>();
  960. }
  961. TEST_F(Atomics, AtomicPtrVariations)
  962. {
  963. validate_atomic_ptr_variations<AZStd::atomic<int*>, int*>();
  964. }
  965. TEST_F(Atomics, AtomicBoolFullSuite)
  966. {
  967. {
  968. volatile AZStd::atomic<bool> obj(true);
  969. EXPECT_TRUE(obj == true);
  970. AZStd::atomic_store(&obj, false);
  971. EXPECT_TRUE(obj == false);
  972. AZStd::atomic_store(&obj, true);
  973. EXPECT_TRUE(obj == true);
  974. bool b0 = obj.is_lock_free();
  975. (void)b0; // to placate scan-build
  976. obj.store(false);
  977. EXPECT_TRUE(obj == false);
  978. obj.store(true, AZStd::memory_order_release);
  979. EXPECT_TRUE(obj == true);
  980. EXPECT_TRUE(obj.load() == true);
  981. EXPECT_TRUE(obj.load(AZStd::memory_order_acquire) == true);
  982. EXPECT_TRUE(obj.exchange(false) == true);
  983. EXPECT_TRUE(obj == false);
  984. EXPECT_TRUE(obj.exchange(true, AZStd::memory_order_relaxed) == false);
  985. EXPECT_TRUE(obj == true);
  986. bool x = obj;
  987. EXPECT_TRUE(cmpxchg_weak_loop(obj, x, false) == true);
  988. EXPECT_TRUE(obj == false);
  989. EXPECT_TRUE(x == true);
  990. EXPECT_TRUE(obj.compare_exchange_weak(x, true,
  991. AZStd::memory_order_seq_cst) == false);
  992. EXPECT_TRUE(obj == false);
  993. EXPECT_TRUE(x == false);
  994. obj.store(true);
  995. x = true;
  996. EXPECT_TRUE(cmpxchg_weak_loop(obj, x, false,
  997. AZStd::memory_order_seq_cst,
  998. AZStd::memory_order_seq_cst) == true);
  999. EXPECT_TRUE(obj == false);
  1000. EXPECT_TRUE(x == true);
  1001. x = true;
  1002. obj.store(true);
  1003. EXPECT_TRUE(obj.compare_exchange_strong(x, false) == true);
  1004. EXPECT_TRUE(obj == false);
  1005. EXPECT_TRUE(x == true);
  1006. EXPECT_TRUE(obj.compare_exchange_strong(x, true,
  1007. AZStd::memory_order_seq_cst) == false);
  1008. EXPECT_TRUE(obj == false);
  1009. EXPECT_TRUE(x == false);
  1010. x = true;
  1011. obj.store(true);
  1012. EXPECT_TRUE(obj.compare_exchange_strong(x, false,
  1013. AZStd::memory_order_seq_cst,
  1014. AZStd::memory_order_seq_cst) == true);
  1015. EXPECT_TRUE(obj == false);
  1016. EXPECT_TRUE(x == true);
  1017. EXPECT_TRUE((obj = false) == false);
  1018. EXPECT_TRUE(obj == false);
  1019. EXPECT_TRUE((obj = true) == true);
  1020. EXPECT_TRUE(obj == true);
  1021. }
  1022. {
  1023. AZStd::atomic<bool> obj(true);
  1024. EXPECT_TRUE(obj == true);
  1025. AZStd::atomic_store(&obj, false);
  1026. EXPECT_TRUE(obj == false);
  1027. AZStd::atomic_store(&obj, true);
  1028. EXPECT_TRUE(obj == true);
  1029. bool b0 = obj.is_lock_free();
  1030. (void)b0; // to placate scan-build
  1031. obj.store(false);
  1032. EXPECT_TRUE(obj == false);
  1033. obj.store(true, AZStd::memory_order_release);
  1034. EXPECT_TRUE(obj == true);
  1035. EXPECT_TRUE(obj.load() == true);
  1036. EXPECT_TRUE(obj.load(AZStd::memory_order_acquire) == true);
  1037. EXPECT_TRUE(obj.exchange(false) == true);
  1038. EXPECT_TRUE(obj == false);
  1039. EXPECT_TRUE(obj.exchange(true, AZStd::memory_order_relaxed) == false);
  1040. EXPECT_TRUE(obj == true);
  1041. bool x = obj;
  1042. EXPECT_TRUE(cmpxchg_weak_loop(obj, x, false) == true);
  1043. EXPECT_TRUE(obj == false);
  1044. EXPECT_TRUE(x == true);
  1045. EXPECT_TRUE(obj.compare_exchange_weak(x, true,
  1046. AZStd::memory_order_seq_cst) == false);
  1047. EXPECT_TRUE(obj == false);
  1048. EXPECT_TRUE(x == false);
  1049. obj.store(true);
  1050. x = true;
  1051. EXPECT_TRUE(cmpxchg_weak_loop(obj, x, false,
  1052. AZStd::memory_order_seq_cst,
  1053. AZStd::memory_order_seq_cst) == true);
  1054. EXPECT_TRUE(obj == false);
  1055. EXPECT_TRUE(x == true);
  1056. x = true;
  1057. obj.store(true);
  1058. EXPECT_TRUE(obj.compare_exchange_strong(x, false) == true);
  1059. EXPECT_TRUE(obj == false);
  1060. EXPECT_TRUE(x == true);
  1061. EXPECT_TRUE(obj.compare_exchange_strong(x, true,
  1062. AZStd::memory_order_seq_cst) == false);
  1063. EXPECT_TRUE(obj == false);
  1064. EXPECT_TRUE(x == false);
  1065. x = true;
  1066. obj.store(true);
  1067. EXPECT_TRUE(obj.compare_exchange_strong(x, false,
  1068. AZStd::memory_order_seq_cst,
  1069. AZStd::memory_order_seq_cst) == true);
  1070. EXPECT_TRUE(obj == false);
  1071. EXPECT_TRUE(x == true);
  1072. EXPECT_TRUE((obj = false) == false);
  1073. EXPECT_TRUE(obj == false);
  1074. EXPECT_TRUE((obj = true) == true);
  1075. EXPECT_TRUE(obj == true);
  1076. }
  1077. {
  1078. AZStd::atomic_bool obj(true);
  1079. EXPECT_TRUE(obj == true);
  1080. AZStd::atomic_store(&obj, false);
  1081. EXPECT_TRUE(obj == false);
  1082. AZStd::atomic_store(&obj, true);
  1083. EXPECT_TRUE(obj == true);
  1084. bool b0 = obj.is_lock_free();
  1085. (void)b0; // to placate scan-build
  1086. obj.store(false);
  1087. EXPECT_TRUE(obj == false);
  1088. obj.store(true, AZStd::memory_order_release);
  1089. EXPECT_TRUE(obj == true);
  1090. EXPECT_TRUE(obj.load() == true);
  1091. EXPECT_TRUE(obj.load(AZStd::memory_order_acquire) == true);
  1092. EXPECT_TRUE(obj.exchange(false) == true);
  1093. EXPECT_TRUE(obj == false);
  1094. EXPECT_TRUE(obj.exchange(true, AZStd::memory_order_relaxed) == false);
  1095. EXPECT_TRUE(obj == true);
  1096. bool x = obj;
  1097. EXPECT_TRUE(cmpxchg_weak_loop(obj, x, false) == true);
  1098. EXPECT_TRUE(obj == false);
  1099. EXPECT_TRUE(x == true);
  1100. EXPECT_TRUE(obj.compare_exchange_weak(x, true,
  1101. AZStd::memory_order_seq_cst) == false);
  1102. EXPECT_TRUE(obj == false);
  1103. EXPECT_TRUE(x == false);
  1104. obj.store(true);
  1105. x = true;
  1106. EXPECT_TRUE(cmpxchg_weak_loop(obj, x, false,
  1107. AZStd::memory_order_seq_cst,
  1108. AZStd::memory_order_seq_cst) == true);
  1109. EXPECT_TRUE(obj == false);
  1110. EXPECT_TRUE(x == true);
  1111. x = true;
  1112. obj.store(true);
  1113. EXPECT_TRUE(obj.compare_exchange_strong(x, false) == true);
  1114. EXPECT_TRUE(obj == false);
  1115. EXPECT_TRUE(x == true);
  1116. EXPECT_TRUE(obj.compare_exchange_strong(x, true,
  1117. AZStd::memory_order_seq_cst) == false);
  1118. EXPECT_TRUE(obj == false);
  1119. EXPECT_TRUE(x == false);
  1120. x = true;
  1121. obj.store(true);
  1122. EXPECT_TRUE(obj.compare_exchange_strong(x, false,
  1123. AZStd::memory_order_seq_cst,
  1124. AZStd::memory_order_seq_cst) == true);
  1125. EXPECT_TRUE(obj == false);
  1126. EXPECT_TRUE(x == true);
  1127. EXPECT_TRUE((obj = false) == false);
  1128. EXPECT_TRUE(obj == false);
  1129. EXPECT_TRUE((obj = true) == true);
  1130. EXPECT_TRUE(obj == true);
  1131. }
  1132. {
  1133. typedef AZStd::atomic<bool> A;
  1134. alignas(A) char storage[sizeof(A)] = { 1 };
  1135. A& zero = *new (storage) A();
  1136. EXPECT_TRUE(zero == false);
  1137. zero.~A();
  1138. }
  1139. }
  1140. template <class A, class T>
  1141. void test_atomic_integral()
  1142. {
  1143. A obj(T(0));
  1144. EXPECT_TRUE(obj == T(0));
  1145. AZStd::atomic_store(&obj, T(1));
  1146. EXPECT_TRUE(obj == T(1));
  1147. AZStd::atomic_store(&obj, T(2));
  1148. EXPECT_TRUE(obj == T(2));
  1149. bool b0 = obj.is_lock_free();
  1150. ((void)b0); // mark as unused
  1151. obj.store(T(0));
  1152. EXPECT_TRUE(obj == T(0));
  1153. obj.store(T(1), AZStd::memory_order_release);
  1154. EXPECT_TRUE(obj == T(1));
  1155. EXPECT_TRUE(obj.load() == T(1));
  1156. EXPECT_TRUE(obj.load(AZStd::memory_order_acquire) == T(1));
  1157. EXPECT_TRUE(obj.exchange(T(2)) == T(1));
  1158. EXPECT_TRUE(obj == T(2));
  1159. EXPECT_TRUE(obj.exchange(T(3), AZStd::memory_order_relaxed) == T(2));
  1160. EXPECT_TRUE(obj == T(3));
  1161. T x = obj;
  1162. EXPECT_TRUE(cmpxchg_weak_loop(obj, x, T(2)) == true);
  1163. EXPECT_TRUE(obj == T(2));
  1164. EXPECT_TRUE(x == T(3));
  1165. EXPECT_TRUE(obj.compare_exchange_weak(x, T(1)) == false);
  1166. EXPECT_TRUE(obj == T(2));
  1167. EXPECT_TRUE(x == T(2));
  1168. x = T(2);
  1169. EXPECT_TRUE(obj.compare_exchange_strong(x, T(1)) == true);
  1170. EXPECT_TRUE(obj == T(1));
  1171. EXPECT_TRUE(x == T(2));
  1172. EXPECT_TRUE(obj.compare_exchange_strong(x, T(0)) == false);
  1173. EXPECT_TRUE(obj == T(1));
  1174. EXPECT_TRUE(x == T(1));
  1175. EXPECT_TRUE((obj = T(0)) == T(0));
  1176. EXPECT_TRUE(obj == T(0));
  1177. EXPECT_TRUE(obj++ == T(0));
  1178. EXPECT_TRUE(obj == T(1));
  1179. EXPECT_TRUE(++obj == T(2));
  1180. EXPECT_TRUE(obj == T(2));
  1181. EXPECT_TRUE(--obj == T(1));
  1182. EXPECT_TRUE(obj == T(1));
  1183. EXPECT_TRUE(obj-- == T(1));
  1184. EXPECT_TRUE(obj == T(0));
  1185. obj = T(2);
  1186. EXPECT_TRUE((obj += T(3)) == T(5));
  1187. EXPECT_TRUE(obj == T(5));
  1188. EXPECT_TRUE((obj -= T(3)) == T(2));
  1189. EXPECT_TRUE(obj == T(2));
  1190. EXPECT_TRUE((obj |= T(5)) == T(7));
  1191. EXPECT_TRUE(obj == T(7));
  1192. EXPECT_TRUE((obj &= T(0xF)) == T(7));
  1193. EXPECT_TRUE(obj == T(7));
  1194. EXPECT_TRUE((obj ^= T(0xF)) == T(8));
  1195. EXPECT_TRUE(obj == T(8));
  1196. {
  1197. alignas(A) char storage[sizeof(A)] = { 23 };
  1198. A& zero = *new (storage) A();
  1199. EXPECT_TRUE(zero == 0);
  1200. zero.~A();
  1201. }
  1202. }
  1203. template <class A, class T>
  1204. void test_atomic_integral_variations()
  1205. {
  1206. test_atomic_integral<A, T>();
  1207. test_atomic_integral<volatile A, T>();
  1208. }
  1209. TEST_F(Atomics, AtomicIntegralsFullSuite)
  1210. {
  1211. // NOTE: wchar_t is not integral in our impl, and schar was removed
  1212. test_atomic_integral_variations<AZStd::atomic_char, char>();
  1213. test_atomic_integral_variations<AZStd::atomic_uchar, unsigned char>();
  1214. test_atomic_integral_variations<AZStd::atomic_short, short>();
  1215. test_atomic_integral_variations<AZStd::atomic_ushort, unsigned short>();
  1216. test_atomic_integral_variations<AZStd::atomic_int, int>();
  1217. test_atomic_integral_variations<AZStd::atomic_uint, unsigned int>();
  1218. test_atomic_integral_variations<AZStd::atomic_long, long>();
  1219. test_atomic_integral_variations<AZStd::atomic_ulong, unsigned long>();
  1220. test_atomic_integral_variations<AZStd::atomic_llong, long long>();
  1221. test_atomic_integral_variations<AZStd::atomic_ullong, unsigned long long>();
  1222. test_atomic_integral_variations<AZStd::atomic_size_t, size_t>();
  1223. test_atomic_integral_variations<AZStd::atomic_ptrdiff_t, ptrdiff_t>();
  1224. test_atomic_integral_variations<AZStd::atomic_int8_t, int8_t>();
  1225. test_atomic_integral_variations<AZStd::atomic_uint8_t, uint8_t>();
  1226. test_atomic_integral_variations<AZStd::atomic_int16_t, int16_t>();
  1227. test_atomic_integral_variations<AZStd::atomic_uint16_t, uint16_t>();
  1228. test_atomic_integral_variations<AZStd::atomic_int32_t, int32_t>();
  1229. test_atomic_integral_variations<AZStd::atomic_uint32_t, uint32_t>();
  1230. test_atomic_integral_variations<AZStd::atomic_int64_t, int64_t>();
  1231. test_atomic_integral_variations<AZStd::atomic_uint64_t, uint64_t>();
  1232. }
  1233. }