1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
/*=========================================================================
Program: OpenIGTLink Library
Language: C++
Copyright (c) Insight Software Consortium. All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
//=========================================================================
//
// MultiThreader Test 1 --- Spawn Thread Test
//
// This test check the behaviour of igtl::MultiThreader::SpawnThread
// and igtl::MutexLock.
// The test create NUM_THREAD threads from a single method that repeats:
//
// s1 = s;
// sleep(interval)
// s2 = s;
// s = s1 + s2;
//
// for NUM_REPEAT times, where 's' is a global variable (shared by all
// threads) initialized with 1, and 's1', 's2' and 'interval' are local
// variables. 'interval' differs from thread to thread.
// If the threads work correctly, and the code block above is properly
// protected by a semaphore, 's' finally becomes 2^(NUM_REPEAT * NUM_THREAD-1).
//
//=========================================================================
#include "igtlMultiThreader.h"
#include "igtlOSUtil.h"
#define EXIT_SUCCESS 0
#define EXIT_FAILURE 1
// NOTE: (NUM_THREAD + NUM_REPEAT) < 32 on 32-bit environment
#if IGTL_MAX_THREADS > 1
#define NUM_THREAD 5
#define NUM_REPEAT 4
#else
#define NUM_THREAD 1
#define NUM_REPEAT 4
#endif
typedef struct {
int nloop;
int *sum;
igtl::MutexLock::Pointer glock;
} ThreadData;
void* ThreadFunction(void* ptr)
{
// Get thread information
igtl::MultiThreader::ThreadInfo* info =
static_cast<igtl::MultiThreader::ThreadInfo*>(ptr);
int id = info->ThreadID;
// Set interval at 100 * id (ms)
long interval = 10*id;
ThreadData* data = static_cast<ThreadData*>(info->UserData);
int nloop = data->nloop;
igtl::MutexLock::Pointer glock = data->glock;
for (int i = 0; i < nloop; i ++)
{
glock->Lock();
int s1 = *(data->sum);
igtl::Sleep(interval);
int s2 = *(data->sum);
*(data->sum) = s1 + s2;
glock->Unlock();
}
return NULL;
}
int main(int , char * [] )
{
igtl::MutexLock::Pointer glock = igtl::MutexLock::New();
int sum = 1;
ThreadData td;
td.nloop = NUM_REPEAT;
td.sum = ∑
td.glock = glock;
igtl::MultiThreader::Pointer threader = igtl::MultiThreader::New();
int id1 = threader->SpawnThread((igtl::ThreadFunctionType) &ThreadFunction, &td);
int id2 = threader->SpawnThread((igtl::ThreadFunctionType) &ThreadFunction, &td);
int id3 = threader->SpawnThread((igtl::ThreadFunctionType) &ThreadFunction, &td);
int id4 = threader->SpawnThread((igtl::ThreadFunctionType) &ThreadFunction, &td);
int id5 = threader->SpawnThread((igtl::ThreadFunctionType) &ThreadFunction, &td);
// wait for the threads
threader->TerminateThread(id1);
threader->TerminateThread(id2);
threader->TerminateThread(id3);
threader->TerminateThread(id4);
threader->TerminateThread(id5);
int answer = 0x00000001;
answer <<= (NUM_THREAD * NUM_REPEAT);
//std::cerr << "sum = " << sum << " answer = " << answer << std::endl;
if (sum == answer)
{
return EXIT_SUCCESS;
}
else
{
return EXIT_FAILURE;
}
}
|