ThreadTests.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. module;
  2. #include "../../src/ErrorSimulator.hpp"
  3. module Tests;
  4. import Core.Test;
  5. import Core.Thread;
  6. import Core.Meta;
  7. static int runDone = 0;
  8. struct IntHolder {
  9. int value;
  10. };
  11. static void run(void*) {
  12. runDone = 1;
  13. }
  14. static void testStart() {
  15. runDone = 0;
  16. {
  17. Core::Thread t;
  18. Core::testFalse(t.start(run, nullptr));
  19. }
  20. Core::test(1, runDone);
  21. }
  22. static void testLambda() {
  23. IntHolder i(0);
  24. Core::Thread t;
  25. Core::testFalse(t.start(
  26. [](void* p) {
  27. IntHolder* ip = static_cast<IntHolder*>(p);
  28. ip->value = 2;
  29. },
  30. &i));
  31. Core::testFalse(t.join());
  32. Core::test(2, i.value);
  33. }
  34. static void testJoinWithoutStart() {
  35. Core::Thread t;
  36. Core::testFalse(t.join());
  37. }
  38. static void testAutoJoin() {
  39. Core::Thread t;
  40. Core::testFalse(t.start([](void*) {}, nullptr));
  41. }
  42. static void testMove() {
  43. Core::Thread t;
  44. Core::testFalse(t.start([](void*) {}, nullptr));
  45. Core::Thread m = Core::move(t);
  46. Core::testFalse(m.join());
  47. }
  48. static void testMoveAssignment() {
  49. Core::Thread t;
  50. Core::testFalse(t.start([](void*) {}, nullptr));
  51. Core::Thread m;
  52. m = Core::move(t);
  53. Core::testFalse(m.join());
  54. }
  55. static void testMoveIntoActive() {
  56. Core::Thread t;
  57. Core::testFalse(t.start([](void*) {}, nullptr));
  58. Core::Thread m;
  59. t = Core::move(m);
  60. }
  61. static void testDoubleJoin() {
  62. Core::Thread t;
  63. Core::testFalse(t.start([](void*) {}, nullptr));
  64. Core::testFalse(t.join());
  65. Core::testFalse(t.join());
  66. }
  67. struct MutexCounter {
  68. Core::Mutex m{};
  69. int counter = 0;
  70. };
  71. static void incrementMutexCounter(void* p) {
  72. MutexCounter* mcp = static_cast<MutexCounter*>(p);
  73. for(int i = 0; i < 100'000; i++) {
  74. Core::MutexGuard mg(mcp->m);
  75. mcp->counter++;
  76. }
  77. }
  78. static void testMutex() {
  79. MutexCounter mc;
  80. Core::Thread t[2];
  81. Core::testFalse(t[0].start(incrementMutexCounter, &mc));
  82. Core::testFalse(t[1].start(incrementMutexCounter, &mc));
  83. Core::testFalse(t[0].join());
  84. Core::testFalse(t[1].join());
  85. Core::test(200'000, mc.counter);
  86. }
  87. static void testDoubleStart() {
  88. Core::Thread t;
  89. Core::testFalse(t.start([](void*) {}, nullptr));
  90. Core::testTrue(t.start([](void*) {}, nullptr));
  91. }
  92. static void testFail() {
  93. #ifdef ERROR_SIMULATOR
  94. Core::Mutex m;
  95. failStepThrow = 1;
  96. m.lock();
  97. failStepThrow = 1;
  98. m.unlock();
  99. Core::Thread t;
  100. failStepThrow = 1;
  101. Core::testTrue(t.start([](void*) {}, nullptr));
  102. Core::testFalse(t.start([](void*) {}, nullptr));
  103. failStepThrow = 1;
  104. Core::testTrue(t.join());
  105. #endif
  106. }
  107. void testThread() {
  108. testStart();
  109. testLambda();
  110. testJoinWithoutStart();
  111. testAutoJoin();
  112. testMove();
  113. testMoveAssignment();
  114. testMoveIntoActive();
  115. testDoubleJoin();
  116. testMutex();
  117. testDoubleStart();
  118. testFail();
  119. }