Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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.