Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkITKThreadingTest.cpp
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
17 #include <itkFastMutexLock.h>
18 #include <itkMultiThreader.h>
19 #include <itkSemaphore.h>
20 
21 /*
22 int main()
23 {
24  std::cout<<"[PASSED]"<<std::endl;
25  std::cout<<"[FAILED]"<<std::endl;
26  return EXIT_FAILURE;
27  return EXIT_SUCCESS;
28 }
29 */
30 
31 // to pass some parameter to thread
32 class UserData
33 {
34 public:
35  int *intPointer;
36  itk::FastMutexLock *mutex;
37  itk::Semaphore *semaphore;
38  itk::Semaphore *mayIRun;
39 };
40 
41 // this will be executed in a thread
42 ITK_THREAD_RETURN_TYPE ThreadedFunction(void *param)
43 {
44  std::cout << "Getting thread info data... ";
45  itk::MultiThreader::ThreadInfoStruct *threadInfo = static_cast<itk::MultiThreader::ThreadInfoStruct *>(param);
46 
47  if (!threadInfo)
48  {
49  std::cout << "[FAILED]" << std::endl;
50  exit(EXIT_FAILURE);
51  }
52  std::cout << "[PASSED]" << std::endl;
53 
54  std::cout << "Getting user data from thread... ";
55  UserData *userData = static_cast<UserData *>(threadInfo->UserData);
56 
57  if (!userData)
58  {
59  std::cout << "[FAILED]" << std::endl;
60  exit(EXIT_FAILURE);
61  }
62  std::cout << "[PASSED]" << std::endl;
63 
64  // inc variable FOR main thread
65  std::cout << "generate 10000 results";
66  for (int i = 1; i <= 10000; ++i)
67  {
68  userData->mutex->Lock();
69  *(userData->intPointer) += 1; // generate one "result"
70  userData->mutex->Unlock();
71  userData->semaphore->Up(); // signal "work done"
72  }
73  std::cout << "[PASSED]" << std::endl;
74 
75  std::cout << "waiting for main thread's signal... " << std::endl;
76  ;
77  userData->mayIRun->Down(); // wait for signal
78  std::cout << "got main thread's signal... " << std::endl;
79 
80  // inc variable TOGETHER WITH main thread
81  for (int i = 1; i <= 10000; ++i)
82  {
83  userData->mutex->Lock();
84  *(userData->intPointer) += 1;
85  userData->mutex->Unlock();
86  }
87 
88  userData->semaphore->Up(); // signal "job done"
89 
90  return ITK_THREAD_RETURN_VALUE;
91 }
92 
93 int mitkITKThreadingTest(int /*argc*/, char * /*argv*/ [])
94 {
96 
97  int localInt(0); // this will be modified by both threads
98 
99  itk::Semaphore::Pointer m_ResultAvailable = itk::Semaphore::New();
100  m_ResultAvailable->Initialize(0); // no pieces left (thread has to create one)
101 
102  itk::Semaphore::Pointer m_RunThreadRun = itk::Semaphore::New();
103  m_RunThreadRun->Initialize(0); // no pieces left (thread has to create one)
104 
106 
107  UserData userData;
108  userData.intPointer = &localInt;
109  userData.mutex = m_Mutex.GetPointer();
110  userData.semaphore = m_ResultAvailable.GetPointer();
111  userData.mayIRun = m_RunThreadRun.GetPointer();
112 
113  itk::ThreadFunctionType pointer = &ThreadedFunction;
114  int thread_id = threader->SpawnThread(pointer, &userData);
115 
116  // let thread generate 10 results
117  for (int i = 1; i <= 10000; ++i)
118  m_ResultAvailable->Down();
119 
120  std::cout << "signaling by semaphore thread->main ";
121  if (localInt == 10000)
122  std::cout << "[PASSED]" << std::endl;
123  else
124  {
125  std::cout << "[FAILED] localInt == " << localInt << std::endl;
126  return EXIT_FAILURE;
127  }
128 
129  // increase int simultaneously with thread (coordinated by mutex)
130  localInt = 0;
131  m_RunThreadRun->Up(); // let thread work again
132  for (int i = 1; i <= 10000; ++i)
133  {
134  m_Mutex->Lock();
135  ++localInt;
136  m_Mutex->Unlock();
137  }
138 
139  std::cout << "waiting for thread's signal" << std::endl;
140  ;
141  m_ResultAvailable->Down(); // wait for thread
142  std::cout << "got thread's signal" << std::endl;
143  ;
144 
145  std::cout << "sharing a mutex protected variable among threads";
146  if (localInt == 20000)
147  std::cout << "[PASSED]" << std::endl;
148  else
149  {
150  std::cout << "[FAILED] localInt == " << localInt << std::endl;
151  return EXIT_FAILURE;
152  }
153 
154  // terminating work thread
155  std::cout << "waiting for idling thread ";
156  threader->TerminateThread(thread_id);
157  std::cout << "[PASSED]" << std::endl;
158 
159  std::cout << "Whole test [PASSED]" << std::endl;
160 
161  return EXIT_SUCCESS;
162 }
int mitkITKThreadingTest(int, char *[])
itk::SmartPointer< Self > Pointer
ITK_THREAD_RETURN_TYPE ThreadedFunction(void *param)
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.