diff options
Diffstat (limited to 'tests/testAtomic.cpp')
-rw-r--r-- | tests/testAtomic.cpp | 258 |
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; +} + + |