merge new MTDM code from Fons' latest release.
[jack2.git] / tests / testAtomic.cpp
blob4c79cc5257a67ca355d531e1f0400e42c60668c2
1 /*
2 Copyright (C) 2004-2008 Grame
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include <iostream>
21 #include <unistd.h>
23 #include "JackAtomicState.h"
24 #include "JackPosixThread.h"
26 using namespace Jack;
28 #define SIZE 1024
30 struct TestState {
32 long fTable[SIZE];
33 long fReadCounter;
34 long fWriteCounter;
36 TestState()
38 for (int i = 0; i < SIZE; i++) {
39 fTable[i] = 0;
41 fReadCounter = 0;
42 fWriteCounter = 0;
44 virtual ~TestState()
47 void Write()
49 fWriteCounter++;
50 for (int i = 0; i < SIZE; i++) {
51 fTable[i] = fTable[i] + 10;
55 bool Read()
57 int val = fTable[0];
58 fReadCounter++;
59 for (int i = 0; i < SIZE; i++) {
60 if (fTable[i] != val) {
61 printf("Read error fReadCounter %ld, i %ld, curVal %ld, oldVal %ld\n", fReadCounter, i, fTable[i], val);
62 return false;
65 return true;
68 bool ReadCopy(long* result)
70 int val = fTable[0];
71 fReadCounter++;
72 for (int i = 0; i < SIZE; i++) {
73 result[i] = fTable[i];
74 if (fTable[i] != val) {
75 //printf("ReadCopy error fReadCounter %ld, i %ld, curVal %ld, oldVal %ld\n", fReadCounter, i, fTable[i], val);
76 return false;
79 return true;
82 bool Check(long* result)
84 int val = result[0];
85 for (int i = 0; i < SIZE; i++) {
86 if (result[i] != val) {
87 printf("Check error fReadCounter %ld, i %ld, curVal %ld, oldVal %ld\n", fReadCounter, i, fTable[i], val);
88 return false;
91 return true;
94 int GetVal()
96 return fTable[10];
99 };
102 \brief The state wrapped with the 2 state atomic class.
105 class TestStateUser : public JackAtomicState<TestState> {
107 public:
109 TestStateUser(){}
110 virtual ~TestStateUser(){}
112 void TestWriteMethod()
114 TestState* state = WriteNextStateStart();
115 state->Write();
116 state->Write();
117 state->Write();
118 WriteNextStateStop();
121 void TestReadMethod()
123 TestState* state;
124 int fCount = 0;
125 long result[SIZE];
126 UInt16 cur_index;
127 UInt16 next_index;
128 do {
129 cur_index = GetCurrentIndex();
130 fCount++;
131 state = ReadCurrentState();
132 bool res = state->ReadCopy(result);
133 next_index = GetCurrentIndex();
134 if (!res)
135 printf("TestReadMethod fCount %ld cur %ld next %ld\n", fCount, cur_index, next_index);
136 }while (cur_index != next_index);
137 state->Check(result);
140 void TestReadRTMethod1()
142 TestState* state = TrySwitchState();
143 bool res = state->Read();
146 void TestReadRTMethod2()
148 TestState* state = ReadCurrentState();
149 state->Read();
154 \brief Base class for reader/writer threads.
157 struct TestThread : public JackRunnableInterface {
159 JackPosixThread* fThread;
160 TestStateUser* fObject;
162 TestThread(TestStateUser* state):fObject(state)
164 fThread = new JackPosixThread(this);
165 int res = fThread->Start();
168 virtual ~TestThread()
170 fThread->Kill();
171 delete fThread;
177 \brief "Real-time" reader thread.
180 struct RTReaderThread : public TestThread {
182 RTReaderThread(TestStateUser* state):TestThread(state)
185 bool Execute()
187 fObject->TestReadRTMethod1();
189 for (int i = 0; i < 5; i++) {
190 fObject->TestReadRTMethod2();
193 usleep(50);
194 return true;
199 \brief Non "Real-time" reader thread.
202 struct ReaderThread : public TestThread {
204 ReaderThread(TestStateUser* state):TestThread(state)
207 bool Execute()
209 fObject->TestReadMethod();
210 usleep(56);
211 return true;
216 \brief Writer thread.
219 struct WriterThread : public TestThread {
221 WriterThread(TestStateUser* state):TestThread(state)
224 bool Execute()
226 fObject->TestWriteMethod();
227 usleep(75);
228 return true;
233 int main(int argc, char * const argv[])
235 char c;
237 printf("Test concurrent access to a TestState data structure protected with the 2 state JackAtomicState class\n");
239 TestStateUser fObject;
240 WriterThread writer(&fObject);
241 RTReaderThread readerRT1(&fObject);
242 ReaderThread reader1(&fObject);
245 ReaderThread reader2(&fObject);
246 ReaderThread reader3(&fObject);
247 ReaderThread reader4(&fObject);
248 ReaderThread reader5(&fObject);
249 ReaderThread reader6(&fObject);
252 while ((c = getchar()) != 'q') {}
253 return 1;