31 template<
typename arrayType,
typename iteratorType>
32 static void thread_reads_array(arrayType shared_array,
int setValue) {
33 while (!ThreadTestManager::s_bAllowThreadsToRun) {}
34 for(
int n = 0;
n < 1000; ++
n) {
35 for (iteratorType iter = shared_array->begin();
36 iter < shared_array->end(); ++iter) {
37 int readValue = *iter;
38 if(readValue != setValue) {
39 throw std::logic_error(
"Test failed to read proper array value.");
47 template<
typename arrayType,
typename iteratorType>
48 void runReadArrayTest()
52 const int setArrayLength = 10;
53 const int setArrayValue = 3;
54 for (
int testCycle = 0; testCycle < numTests; ++testCycle) {
55 std::vector<std::thread> threads;
57 ThreadTestManager::s_bAllowThreadsToRun =
false;
61 rcp(
new Array<int>( setArrayLength, setArrayValue ));
63 for (
int i = 0; i < numThreads; ++i) {
64 threads.push_back(std::thread(
65 thread_reads_array<arrayType, iteratorType>,
66 array_rcp, setArrayValue));
69 ThreadTestManager::s_bAllowThreadsToRun =
true;
71 for (
unsigned int i = 0; i < threads.size(); ++i) {
74 convenience_log_progress(testCycle, numTests);
147 static void call_inserts_on_array(RCP<Array<int>> shared_array,
int setValue,
148 int maxArraySize,
int finishWhenThisThreadCountCompletes) {
149 while (!ThreadTestManager::s_bAllowThreadsToRun) {}
151 const int insertCount = maxArraySize - shared_array->size();
153 for (
int n = 0;
n < insertCount; ++
n) {
154 shared_array->push_back(setValue);
157 for (
int n = 0;
n < insertCount; ++
n) {
158 shared_array->pop_back();
160 if (ThreadTestManager::s_countCompletedThreads >=
161 finishWhenThisThreadCountCompletes) {
166 ++ThreadTestManager::s_countWritingThreadCycles;
177 static void scramble_memory(
int scrambleValue,
178 int finishWhenThisThreadCountCompletes) {
179 while (!ThreadTestManager::s_bAllowThreadsToRun) {}
186 #define ARRAY_SCRAMBLE_SIZE 100
187 int * tempPtrArray[ARRAY_SCRAMBLE_SIZE];
188 for (
int n = 0;
n < ARRAY_SCRAMBLE_SIZE; ++
n) {
189 int * pInt =
new int;
190 *pInt = scrambleValue;
191 tempPtrArray[
n] = pInt;
193 for (
int n = 0;
n < ARRAY_SCRAMBLE_SIZE; ++
n) {
194 delete tempPtrArray[
n];
196 if (ThreadTestManager::s_countCompletedThreads >=
197 finishWhenThisThreadCountCompletes) {
207 enum ArrayTest_Style {
210 ArrayTest_DoReadOperations,
214 ArrayTest_TriggerDanglingWithIteration,
218 ArrayTest_TriggerDanglingWithIterationFirstCycle
225 template<
class arrayType>
226 static void do_read_operations_on_array(RCP<arrayType> shared_array,
227 int setValue,
int scrambleValue, Cycle_Index_Tracker & index_tracker,
228 int maxArraySize, ArrayTest_Style arrayTestStyle) {
230 while (!ThreadTestManager::s_bAllowThreadsToRun) {}
236 for (cycle = 0; cycle < 10000; ++cycle) {
237 switch (arrayTestStyle) {
238 case ArrayTest_DoReadOperations:
244 int readValue = shared_array->at(0);
245 if( readValue != setValue ) {
249 if( readValue == scrambleValue) {
253 index_tracker.scambledMemory = cycle;
262 index_tracker.scambledMemory = cycle;
267 case ArrayTest_TriggerDanglingWithIteration:
284 iter < shared_array->end(); ++iter) {
291 case ArrayTest_TriggerDanglingWithIterationFirstCycle:
298 index_tracker.missedDanglingOnFirstCycle = cycle;
302 ++ThreadTestManager::s_countCompletedThreads;
313 int getReadWriteThreadCycles =
314 ThreadTestManager::s_countWritingThreadCycles;
319 while (ThreadTestManager::s_countWritingThreadCycles <
320 getReadWriteThreadCycles + 2) {
332 catch (DanglingReferenceError&) {
334 index_tracker.danglingReference = cycle;
336 catch (RangeError&) {
338 index_tracker.outOfRangeError = cycle;
340 catch (std::out_of_range&) {
346 index_tracker.outOfRangeError = cycle;
351 ++ThreadTestManager::s_countCompletedThreads;
361 bool runArrayDanglingReferenceTest(
bool bUseConstVersion,
362 ArrayTest_Style arrayTestStyle ) {
372 const int setValue = 1;
380 const int scrambleValue = 12345;
384 const int maxArraySize = 100;
389 int countTotalTestRuns = 0;
392 int countDetectedDanglingReferences = 0;
395 int countMissedFirstCycleDanglers = 0;
400 int countScrambledMemoryEvents = 0;
405 int countOutOfRangeEvents = 0;
407 for (
int testCycle = 0; testCycle < numTests; ++testCycle) {
408 std::vector<std::thread> threads;
409 ThreadTestManager::s_bAllowThreadsToRun =
false;
410 ThreadTestManager::s_countCompletedThreads = 0;
411 ThreadTestManager::s_countWritingThreadCycles = 0;
415 int finishWhenThisThreadCountCompletes = numThreads - 2;
419 Cycle_Index_Tracker index_tracker[numThreads];
423 RCP<Array<int>> array_rcp =
rcp(
new Array<int>(1, setValue));
425 for (
int i = 0; i < numThreads; ++i) {
431 threads.push_back( std::thread(call_inserts_on_array, array_rcp,
432 setValue, maxArraySize, finishWhenThisThreadCountCompletes) );
439 threads.push_back( std::thread(scramble_memory, scrambleValue,
440 finishWhenThisThreadCountCompletes) );
445 ++countTotalTestRuns;
446 if (bUseConstVersion) {
447 threads.push_back( std::thread(
448 do_read_operations_on_array<
const Array<int> >, array_rcp,
449 setValue, scrambleValue, std::ref(index_tracker[i]),
450 maxArraySize, arrayTestStyle));
453 threads.push_back( std::thread(
454 do_read_operations_on_array< Array<int> >, array_rcp,
455 setValue, scrambleValue, std::ref(index_tracker[i]),
456 maxArraySize, arrayTestStyle));
463 ThreadTestManager::s_bAllowThreadsToRun =
true;
466 for (
unsigned int i = 0; i < threads.size(); ++i) {
471 for (
unsigned int i = 0; i < threads.size(); ++i) {
474 ++countDetectedDanglingReferences;
480 ++countScrambledMemoryEvents;
485 ++countOutOfRangeEvents;
491 if (arrayTestStyle == ArrayTest_TriggerDanglingWithIterationFirstCycle
493 ++countMissedFirstCycleDanglers;
496 convenience_log_progress(testCycle, numTests);
500 switch (arrayTestStyle) {
501 case ArrayTest_DoReadOperations:
511 std::cout <<
"Range Errors: " << countOutOfRangeEvents <<
512 " Scrambles: " << countScrambledMemoryEvents <<
" ";
515 case ArrayTest_TriggerDanglingWithIterationFirstCycle:
516 case ArrayTest_TriggerDanglingWithIteration:
520 std::cout <<
"Danglers: " << countDetectedDanglingReferences <<
" ";
528 bool bPassed_DetectDanglers = (arrayTestStyle != ArrayTest_DoReadOperations)
529 ? (countDetectedDanglingReferences == countTotalTestRuns) :
true;
535 bool bPassed_DetectDanglersFirstCycle = (countMissedFirstCycleDanglers == 0);
540 bool bPassed_CountOutOfRangeErrors =
541 (arrayTestStyle == ArrayTest_DoReadOperations) ?
542 (countOutOfRangeEvents != 0) : (countOutOfRangeEvents == 0);
549 if(
NUM_TESTS_TO_RUN < 1000 && arrayTestStyle == ArrayTest_DoReadOperations) {
550 if(countOutOfRangeEvents == 0) {
551 bPassed_CountOutOfRangeErrors =
true;
557 bool bPass = bPassed_DetectDanglersFirstCycle &&
558 bPassed_DetectDanglersFirstCycle && bPassed_CountOutOfRangeErrors;
561 std::cout << std::endl;
565 if (!bPassed_DetectDanglers) {
566 std::cout <<
"Test FAILED because it detected only " <<
567 countDetectedDanglingReferences <<
568 " Dangling References but should have detected " << countTotalTestRuns
572 if( !bPassed_DetectDanglersFirstCycle ) {
573 std::cout <<
"Test FAILED because it missed " <<
574 countMissedFirstCycleDanglers <<
575 " Dangling References but should have detected " << countTotalTestRuns
576 <<
" on the first cycle." << std::endl;
579 if( !bPassed_CountOutOfRangeErrors ) {
580 std::cout <<
"Test FAILED because it detected " <<
581 countOutOfRangeEvents <<
582 " out of range events but should have detected: "
583 << ( (arrayTestStyle == ArrayTest_DoReadOperations) ?
584 "More Than 0" :
"0" ) << std::endl;
615 bPass = runArrayDanglingReferenceTest(
false,
616 ArrayTest_DoReadOperations );
640 bPass = runArrayDanglingReferenceTest(
true,
641 ArrayTest_DoReadOperations );
668 bPass = runArrayDanglingReferenceTest(
false,
669 ArrayTest_TriggerDanglingWithIteration );
692 bPass = runArrayDanglingReferenceTest(
true,
693 ArrayTest_TriggerDanglingWithIteration );
720 bPass = runArrayDanglingReferenceTest(
false,
721 ArrayTest_TriggerDanglingWithIterationFirstCycle );
744 bPass = runArrayDanglingReferenceTest(
true,
745 ArrayTest_TriggerDanglingWithIterationFirstCycle );
751 #endif // TEUCHOS_DEBUG
Dangling reference error exception class.
RCP< T > rcp(const boost::shared_ptr< T > &sptr)
Conversion function that takes in a boost::shared_ptr object and spits out a Teuchos::RCP object...
#define TEST_ASSERT(v1)
Assert the given statement is true.
#define TEUCHOS_THREAD_SAFE_UNIT_TESTS_THREADS_USED
#define TEUCHOS_UNIT_TEST(TEST_GROUP, TEST_NAME)
Macro for defining a (non-templated) unit test.
#define UNSET_CYCLE_INDEX
#define TEUCHOS_STANDARD_CATCH_STATEMENTS(VERBOSE, ERR_STREAM, SUCCESS_FLAG)
Simple macro that catches and reports standard exceptions and other exceptions.
std::vector< int >::const_iterator const_iterator
The type of a const forward iterator.
Templated array class derived from the STL std::vector.
Smart reference counting pointer class for automatic garbage collection.
Range error exception class.
std::vector< int >::iterator iterator
The type of a forward iterator.
Reference-counted pointer class and non-member templated function implementations.
Replacement for std::vector that is compatible with the Teuchos Memory Management classes...