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
|
/*=========================================================================
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 --- Single Method Test
//
// This test check the behaviour of igtl::MultiThreader::SingleMethodExecute()
// 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();
threader->SetNumberOfThreads(NUM_THREAD);
threader->SetSingleMethod((igtl::ThreadFunctionType) &ThreadFunction, &td);
threader->SingleMethodExecute();
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;
}
}
|