summaryrefslogtreecommitdiff
path: root/tests/testAtomic.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/testAtomic.cpp')
-rw-r--r--tests/testAtomic.cpp258
1 files changed, 258 insertions, 0 deletions
diff --git a/tests/testAtomic.cpp b/tests/testAtomic.cpp
new file mode 100644
index 00000000..211ce0e5
--- /dev/null
+++ b/tests/testAtomic.cpp
@@ -0,0 +1,258 @@
+/*
+ Copyright (C) 2004-2006 Grame
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <iostream>
+#include <unistd.h>
+
+#include "JackAtomicState.h"
+#include "JackPosixThread.h"
+
+using namespace Jack;
+
+int verbose = 0;
+
+#define SIZE 1024
+
+struct TestState {
+
+ long fTable[SIZE];
+ long fReadCounter;
+ long fWriteCounter;
+
+ TestState()
+ {
+ for (int i = 0; i < SIZE; i++) {
+ fTable[i] = 0;
+ }
+ fReadCounter = 0;
+ fWriteCounter = 0;
+ }
+ virtual ~TestState()
+ {}
+
+ void Write()
+ {
+ fWriteCounter++;
+ for (int i = 0; i < SIZE; i++) {
+ fTable[i] = fTable[i] + 10;
+ }
+ }
+
+ bool Read()
+ {
+ int val = fTable[0];
+ fReadCounter++;
+ for (int i = 0; i < SIZE; i++) {
+ if (fTable[i] != val) {
+ printf("Read error fReadCounter %ld, i %ld, curVal %ld, oldVal %ld\n", fReadCounter, i, fTable[i], val);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ bool ReadCopy(long* result)
+ {
+ int val = fTable[0];
+ fReadCounter++;
+ for (int i = 0; i < SIZE; i++) {
+ result[i] = fTable[i];
+ if (fTable[i] != val) {
+ //printf("ReadCopy error fReadCounter %ld, i %ld, curVal %ld, oldVal %ld\n", fReadCounter, i, fTable[i], val);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ bool Check(long* result)
+ {
+ int val = result[0];
+ for (int i = 0; i < SIZE; i++) {
+ if (result[i] != val) {
+ printf("Check error fReadCounter %ld, i %ld, curVal %ld, oldVal %ld\n", fReadCounter, i, fTable[i], val);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ int GetVal()
+ {
+ return fTable[10];
+ }
+
+};
+
+/*!
+\brief The state wrapped with the 2 state atomic class.
+*/
+
+class TestStateUser : public JackAtomicState<TestState> {
+
+ public:
+
+ TestStateUser(){}
+ virtual ~TestStateUser(){}
+
+ void TestWriteMethod()
+ {
+ TestState* state = WriteNextStateStart();
+ state->Write();
+ state->Write();
+ state->Write();
+ WriteNextStateStop();
+ }
+
+ void TestReadMethod()
+ {
+ TestState* state;
+ int fCount = 0;
+ long result[SIZE];
+ UInt16 cur_index;
+ UInt16 next_index;
+ do {
+ cur_index = GetCurrentIndex();
+ fCount++;
+ state = ReadCurrentState();
+ bool res = state->ReadCopy(result);
+ next_index = GetCurrentIndex();
+ if (!res)
+ printf("TestReadMethod fCount %ld cur %ld next %ld\n", fCount, cur_index, next_index);
+ }while (cur_index != next_index);
+ state->Check(result);
+ }
+
+ void TestReadRTMethod1()
+ {
+ TestState* state = TrySwitchState();
+ bool res = state->Read();
+ }
+
+ void TestReadRTMethod2()
+ {
+ TestState* state = ReadCurrentState();
+ state->Read();
+ }
+};
+
+/*!
+\brief Base class for reader/writer threads.
+*/
+
+struct TestThread : public JackRunnableInterface {
+
+ JackPosixThread* fThread;
+ TestStateUser* fObject;
+
+ TestThread(TestStateUser* state):fObject(state)
+ {
+ fThread = new JackPosixThread(this);
+ int res = fThread->Start();
+ }
+
+ virtual ~TestThread()
+ {
+ fThread->Kill();
+ delete fThread;
+ }
+
+};
+
+/*!
+\brief "Real-time" reader thread.
+*/
+
+struct RTReaderThread : public TestThread {
+
+ RTReaderThread(TestStateUser* state):TestThread(state)
+ {}
+
+ bool Execute()
+ {
+ fObject->TestReadRTMethod1();
+
+ for (int i = 0; i < 5; i++) {
+ fObject->TestReadRTMethod2();
+ }
+
+ usleep(50);
+ return true;
+ }
+};
+
+/*!
+\brief Non "Real-time" reader thread.
+*/
+
+struct ReaderThread : public TestThread {
+
+ ReaderThread(TestStateUser* state):TestThread(state)
+ {}
+
+ bool Execute()
+ {
+ fObject->TestReadMethod();
+ usleep(56);
+ return true;
+ }
+};
+
+/*!
+\brief Writer thread.
+*/
+
+struct WriterThread : public TestThread {
+
+ WriterThread(TestStateUser* state):TestThread(state)
+ {}
+
+ bool Execute()
+ {
+ fObject->TestWriteMethod();
+ usleep(75);
+ return true;
+ }
+};
+
+
+int main(int argc, char * const argv[])
+{
+ char c;
+
+ printf("Test concurrent access to a TestState data structure protected with the 2 state JackAtomicState class\n");
+
+ TestStateUser fObject;
+ WriterThread writer(&fObject);
+ RTReaderThread readerRT1(&fObject);
+ ReaderThread reader1(&fObject);
+
+ /*
+ ReaderThread reader2(&fObject);
+ ReaderThread reader3(&fObject);
+ ReaderThread reader4(&fObject);
+ ReaderThread reader5(&fObject);
+ ReaderThread reader6(&fObject);
+ */
+
+ while ((c = getchar()) != 'q') {}
+ return 1;
+}
+
+