File: igtlMultiThreaderTest1.cxx

package info (click to toggle)
openigtlink 3.0.0-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 3,080 kB
  • sloc: cpp: 20,076; ansic: 6,704; sh: 227; perl: 74; makefile: 46
file content (123 lines) | stat: -rw-r--r-- 2,977 bytes parent folder | download
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   = &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;
    }
}