1 /*========================================================================= 2 3 Program: Visualization Toolkit 4 Module: otherArrays.cxx 5 6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 7 All rights reserved. 8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details. 9 10 This software is distributed WITHOUT ANY WARRANTY; without even 11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 12 PURPOSE. See the above copyright notice for more information. 13 14 =========================================================================*/ 15 #include "vtkAtomicInt.h" 16 #include "vtkNew.h" 17 #include "vtkObjectFactory.h" 18 #include "vtkMultiThreader.h" 19 20 static int Total = 0; 21 static vtkTypeInt64 Total64 = 0; 22 static vtkAtomicInt<vtkTypeInt32> TotalAtomic(0); 23 static vtkAtomicInt<vtkTypeInt64> TotalAtomic64(0); 24 static const int Target = 1000000; 25 static int Values32[Target+2]; 26 static int Values64[Target+2]; 27 static int NumThreads = 5; 28 29 static vtkObject* AnObject; 30 MyFunction(void *)31VTK_THREAD_RETURN_TYPE MyFunction(void *) 32 { 33 for (int i=0; i<Target/NumThreads; i++) 34 { 35 Total++; 36 int idx = ++TotalAtomic; 37 Values32[idx] = 1; 38 39 Total64++; 40 idx = ++TotalAtomic64; 41 Values64[idx] = 1; 42 43 //AnObject->Register(0); 44 //AnObject->UnRegister(0); 45 46 AnObject->Modified(); 47 } 48 49 return VTK_THREAD_RETURN_VALUE; 50 } 51 MyFunction2(void *)52VTK_THREAD_RETURN_TYPE MyFunction2(void *) 53 { 54 for (int i=0; i<Target/NumThreads; i++) 55 { 56 --TotalAtomic; 57 58 --TotalAtomic64; 59 } 60 61 return VTK_THREAD_RETURN_VALUE; 62 } 63 MyFunction3(void *)64VTK_THREAD_RETURN_TYPE MyFunction3(void *) 65 { 66 for (int i=0; i<Target/NumThreads; i++) 67 { 68 int idx = TotalAtomic += 1; 69 Values32[idx]++; 70 71 idx = TotalAtomic64 += 1; 72 Values64[idx]++; 73 } 74 75 return VTK_THREAD_RETURN_VALUE; 76 } 77 MyFunction4(void *)78VTK_THREAD_RETURN_TYPE MyFunction4(void *) 79 { 80 for (int i=0; i<Target/NumThreads; i++) 81 { 82 TotalAtomic++; 83 TotalAtomic += 1; 84 TotalAtomic--; 85 TotalAtomic -= 1; 86 87 TotalAtomic64++; 88 TotalAtomic64 += 1; 89 TotalAtomic64--; 90 TotalAtomic64 -= 1; 91 } 92 93 return VTK_THREAD_RETURN_VALUE; 94 } 95 TestAtomic(int,char * [])96int TestAtomic(int, char*[]) 97 { 98 Total = 0; 99 TotalAtomic = 0; 100 Total64 = 0; 101 TotalAtomic64 = 0; 102 103 AnObject = vtkObject::New(); 104 105 //cout << AnObject->GetReferenceCount() << endl; 106 107 int beforeMTime = AnObject->GetMTime(); 108 109 for (int i=0; i<Target; i++) 110 { 111 Values32[i] = 0; 112 Values64[i] = 0; 113 } 114 115 vtkNew<vtkMultiThreader> mt; 116 mt->SetSingleMethod(MyFunction, NULL); 117 mt->SetNumberOfThreads(NumThreads); 118 mt->SingleMethodExecute(); 119 120 mt->SetSingleMethod(MyFunction2, NULL); 121 mt->SingleMethodExecute(); 122 123 mt->SetSingleMethod(MyFunction3, NULL); 124 mt->SingleMethodExecute(); 125 126 // Making sure that atomic incr returned unique 127 // values each time. We expect all numbers from 128 // 1 to Target-1 to be 2. 129 if (Values32[0] != 0) 130 { 131 cout << "Expecting Values32[0] to be 0. Got " 132 << Values32[0] << endl; 133 return 1; 134 } 135 if (Values64[0] != 0) 136 { 137 cout << "Expecting Values64[0] to be 0. Got " 138 << Values64[0] << endl; 139 return 1; 140 } 141 for (int i=1; i<Target; i++) 142 { 143 if (Values32[i] != 2) 144 { 145 cout << "Expecting Values32[" << i << "] to be 2. Got " 146 << Values32[i] << endl; 147 return 1; 148 } 149 if (Values64[i] != 2) 150 { 151 cout << "Expecting Values64[" << i << "] to be 2. Got " 152 << Values64[i] << endl; 153 return 1; 154 } 155 } 156 157 mt->SetSingleMethod(MyFunction4, NULL); 158 mt->SingleMethodExecute(); 159 160 cout << Total << " " << TotalAtomic.load() << endl; 161 cout << Total64 << " " << TotalAtomic64.load() << endl; 162 163 //cout << AnObject->GetReferenceCount() << endl; 164 165 cout << "MTime: " << AnObject->GetMTime() << endl; 166 167 if (TotalAtomic.load() != Target) 168 { 169 return 1; 170 } 171 172 if (TotalAtomic64.load() != Target) 173 { 174 return 1; 175 } 176 177 if (AnObject->GetReferenceCount() != 1) 178 { 179 return 1; 180 } 181 182 if ((int)AnObject->GetMTime() != Target + beforeMTime + 2) 183 { 184 return 1; 185 } 186 187 AnObject->Delete(); 188 return 0; 189 } 190