jack2 codebase
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

257 lines
4.8KB

  1. /*
  2. Copyright (C) 2004-2008 Grame
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  14. */
  15. #include <iostream>
  16. #include <unistd.h>
  17. #include "JackAtomicState.h"
  18. #include "JackPosixThread.h"
  19. using namespace Jack;
  20. #define SIZE 1024
  21. struct TestState {
  22. long fTable[SIZE];
  23. long fReadCounter;
  24. long fWriteCounter;
  25. TestState()
  26. {
  27. for (int i = 0; i < SIZE; i++) {
  28. fTable[i] = 0;
  29. }
  30. fReadCounter = 0;
  31. fWriteCounter = 0;
  32. }
  33. virtual ~TestState()
  34. {}
  35. void Write()
  36. {
  37. fWriteCounter++;
  38. for (int i = 0; i < SIZE; i++) {
  39. fTable[i] = fTable[i] + 10;
  40. }
  41. }
  42. bool Read()
  43. {
  44. int val = fTable[0];
  45. fReadCounter++;
  46. for (int i = 0; i < SIZE; i++) {
  47. if (fTable[i] != val) {
  48. printf("Read error fReadCounter %ld, i %ld, curVal %ld, oldVal %ld\n", fReadCounter, i, fTable[i], val);
  49. return false;
  50. }
  51. }
  52. return true;
  53. }
  54. bool ReadCopy(long* result)
  55. {
  56. int val = fTable[0];
  57. fReadCounter++;
  58. for (int i = 0; i < SIZE; i++) {
  59. result[i] = fTable[i];
  60. if (fTable[i] != val) {
  61. //printf("ReadCopy error fReadCounter %ld, i %ld, curVal %ld, oldVal %ld\n", fReadCounter, i, fTable[i], val);
  62. return false;
  63. }
  64. }
  65. return true;
  66. }
  67. bool Check(long* result)
  68. {
  69. int val = result[0];
  70. for (int i = 0; i < SIZE; i++) {
  71. if (result[i] != val) {
  72. printf("Check error fReadCounter %ld, i %ld, curVal %ld, oldVal %ld\n", fReadCounter, i, fTable[i], val);
  73. return false;
  74. }
  75. }
  76. return true;
  77. }
  78. int GetVal()
  79. {
  80. return fTable[10];
  81. }
  82. };
  83. /*!
  84. \brief The state wrapped with the 2 state atomic class.
  85. */
  86. class TestStateUser : public JackAtomicState<TestState> {
  87. public:
  88. TestStateUser(){}
  89. virtual ~TestStateUser(){}
  90. void TestWriteMethod()
  91. {
  92. TestState* state = WriteNextStateStart();
  93. state->Write();
  94. state->Write();
  95. state->Write();
  96. WriteNextStateStop();
  97. }
  98. void TestReadMethod()
  99. {
  100. TestState* state;
  101. int fCount = 0;
  102. long result[SIZE];
  103. UInt16 cur_index;
  104. UInt16 next_index;
  105. do {
  106. cur_index = GetCurrentIndex();
  107. fCount++;
  108. state = ReadCurrentState();
  109. bool res = state->ReadCopy(result);
  110. next_index = GetCurrentIndex();
  111. if (!res)
  112. printf("TestReadMethod fCount %ld cur %ld next %ld\n", fCount, cur_index, next_index);
  113. }while (cur_index != next_index);
  114. state->Check(result);
  115. }
  116. void TestReadRTMethod1()
  117. {
  118. TestState* state = TrySwitchState();
  119. bool res = state->Read();
  120. }
  121. void TestReadRTMethod2()
  122. {
  123. TestState* state = ReadCurrentState();
  124. state->Read();
  125. }
  126. };
  127. /*!
  128. \brief Base class for reader/writer threads.
  129. */
  130. struct TestThread : public JackRunnableInterface {
  131. JackPosixThread* fThread;
  132. TestStateUser* fObject;
  133. TestThread(TestStateUser* state):fObject(state)
  134. {
  135. fThread = new JackPosixThread(this);
  136. int res = fThread->Start();
  137. }
  138. virtual ~TestThread()
  139. {
  140. fThread->Kill();
  141. delete fThread;
  142. }
  143. };
  144. /*!
  145. \brief "Real-time" reader thread.
  146. */
  147. struct RTReaderThread : public TestThread {
  148. RTReaderThread(TestStateUser* state):TestThread(state)
  149. {}
  150. bool Execute()
  151. {
  152. fObject->TestReadRTMethod1();
  153. for (int i = 0; i < 5; i++) {
  154. fObject->TestReadRTMethod2();
  155. }
  156. usleep(50);
  157. return true;
  158. }
  159. };
  160. /*!
  161. \brief Non "Real-time" reader thread.
  162. */
  163. struct ReaderThread : public TestThread {
  164. ReaderThread(TestStateUser* state):TestThread(state)
  165. {}
  166. bool Execute()
  167. {
  168. fObject->TestReadMethod();
  169. usleep(56);
  170. return true;
  171. }
  172. };
  173. /*!
  174. \brief Writer thread.
  175. */
  176. struct WriterThread : public TestThread {
  177. WriterThread(TestStateUser* state):TestThread(state)
  178. {}
  179. bool Execute()
  180. {
  181. fObject->TestWriteMethod();
  182. usleep(75);
  183. return true;
  184. }
  185. };
  186. int main(int argc, char * const argv[])
  187. {
  188. char c;
  189. printf("Test concurrent access to a TestState data structure protected with the 2 state JackAtomicState class\n");
  190. TestStateUser fObject;
  191. WriterThread writer(&fObject);
  192. RTReaderThread readerRT1(&fObject);
  193. ReaderThread reader1(&fObject);
  194. /*
  195. ReaderThread reader2(&fObject);
  196. ReaderThread reader3(&fObject);
  197. ReaderThread reader4(&fObject);
  198. ReaderThread reader5(&fObject);
  199. ReaderThread reader6(&fObject);
  200. */
  201. while ((c = getchar()) != 'q') {}
  202. return 1;
  203. }