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.

259 lines
4.8KB

  1. /*
  2. Copyright (C) 2004-2006 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. //int verbose = 0;
  21. #define SIZE 1024
  22. struct TestState {
  23. long fTable[SIZE];
  24. long fReadCounter;
  25. long fWriteCounter;
  26. TestState()
  27. {
  28. for (int i = 0; i < SIZE; i++) {
  29. fTable[i] = 0;
  30. }
  31. fReadCounter = 0;
  32. fWriteCounter = 0;
  33. }
  34. virtual ~TestState()
  35. {}
  36. void Write()
  37. {
  38. fWriteCounter++;
  39. for (int i = 0; i < SIZE; i++) {
  40. fTable[i] = fTable[i] + 10;
  41. }
  42. }
  43. bool Read()
  44. {
  45. int val = fTable[0];
  46. fReadCounter++;
  47. for (int i = 0; i < SIZE; i++) {
  48. if (fTable[i] != val) {
  49. printf("Read error fReadCounter %ld, i %ld, curVal %ld, oldVal %ld\n", fReadCounter, i, fTable[i], val);
  50. return false;
  51. }
  52. }
  53. return true;
  54. }
  55. bool ReadCopy(long* result)
  56. {
  57. int val = fTable[0];
  58. fReadCounter++;
  59. for (int i = 0; i < SIZE; i++) {
  60. result[i] = fTable[i];
  61. if (fTable[i] != val) {
  62. //printf("ReadCopy error fReadCounter %ld, i %ld, curVal %ld, oldVal %ld\n", fReadCounter, i, fTable[i], val);
  63. return false;
  64. }
  65. }
  66. return true;
  67. }
  68. bool Check(long* result)
  69. {
  70. int val = result[0];
  71. for (int i = 0; i < SIZE; i++) {
  72. if (result[i] != val) {
  73. printf("Check error fReadCounter %ld, i %ld, curVal %ld, oldVal %ld\n", fReadCounter, i, fTable[i], val);
  74. return false;
  75. }
  76. }
  77. return true;
  78. }
  79. int GetVal()
  80. {
  81. return fTable[10];
  82. }
  83. };
  84. /*!
  85. \brief The state wrapped with the 2 state atomic class.
  86. */
  87. class TestStateUser : public JackAtomicState<TestState> {
  88. public:
  89. TestStateUser(){}
  90. virtual ~TestStateUser(){}
  91. void TestWriteMethod()
  92. {
  93. TestState* state = WriteNextStateStart();
  94. state->Write();
  95. state->Write();
  96. state->Write();
  97. WriteNextStateStop();
  98. }
  99. void TestReadMethod()
  100. {
  101. TestState* state;
  102. int fCount = 0;
  103. long result[SIZE];
  104. UInt16 cur_index;
  105. UInt16 next_index;
  106. do {
  107. cur_index = GetCurrentIndex();
  108. fCount++;
  109. state = ReadCurrentState();
  110. bool res = state->ReadCopy(result);
  111. next_index = GetCurrentIndex();
  112. if (!res)
  113. printf("TestReadMethod fCount %ld cur %ld next %ld\n", fCount, cur_index, next_index);
  114. }while (cur_index != next_index);
  115. state->Check(result);
  116. }
  117. void TestReadRTMethod1()
  118. {
  119. TestState* state = TrySwitchState();
  120. bool res = state->Read();
  121. }
  122. void TestReadRTMethod2()
  123. {
  124. TestState* state = ReadCurrentState();
  125. state->Read();
  126. }
  127. };
  128. /*!
  129. \brief Base class for reader/writer threads.
  130. */
  131. struct TestThread : public JackRunnableInterface {
  132. JackPosixThread* fThread;
  133. TestStateUser* fObject;
  134. TestThread(TestStateUser* state):fObject(state)
  135. {
  136. fThread = new JackPosixThread(this);
  137. int res = fThread->Start();
  138. }
  139. virtual ~TestThread()
  140. {
  141. fThread->Kill();
  142. delete fThread;
  143. }
  144. };
  145. /*!
  146. \brief "Real-time" reader thread.
  147. */
  148. struct RTReaderThread : public TestThread {
  149. RTReaderThread(TestStateUser* state):TestThread(state)
  150. {}
  151. bool Execute()
  152. {
  153. fObject->TestReadRTMethod1();
  154. for (int i = 0; i < 5; i++) {
  155. fObject->TestReadRTMethod2();
  156. }
  157. usleep(50);
  158. return true;
  159. }
  160. };
  161. /*!
  162. \brief Non "Real-time" reader thread.
  163. */
  164. struct ReaderThread : public TestThread {
  165. ReaderThread(TestStateUser* state):TestThread(state)
  166. {}
  167. bool Execute()
  168. {
  169. fObject->TestReadMethod();
  170. usleep(56);
  171. return true;
  172. }
  173. };
  174. /*!
  175. \brief Writer thread.
  176. */
  177. struct WriterThread : public TestThread {
  178. WriterThread(TestStateUser* state):TestThread(state)
  179. {}
  180. bool Execute()
  181. {
  182. fObject->TestWriteMethod();
  183. usleep(75);
  184. return true;
  185. }
  186. };
  187. int main(int argc, char * const argv[])
  188. {
  189. char c;
  190. printf("Test concurrent access to a TestState data structure protected with the 2 state JackAtomicState class\n");
  191. TestStateUser fObject;
  192. WriterThread writer(&fObject);
  193. RTReaderThread readerRT1(&fObject);
  194. ReaderThread reader1(&fObject);
  195. /*
  196. ReaderThread reader2(&fObject);
  197. ReaderThread reader3(&fObject);
  198. ReaderThread reader4(&fObject);
  199. ReaderThread reader5(&fObject);
  200. ReaderThread reader6(&fObject);
  201. */
  202. while ((c = getchar()) != 'q') {}
  203. return 1;
  204. }