65 template<
typename arrayType,
typename iteratorType>
66 static void thread_reads_array(arrayType shared_array,
int setValue) {
67 while (!ThreadTestManager::s_bAllowThreadsToRun) {}
68 for(
int n = 0;
n < 1000; ++
n) {
69 for (iteratorType iter = shared_array->begin();
70 iter < shared_array->end(); ++iter) {
71 int readValue = *iter;
72 if(readValue != setValue) {
73 throw std::logic_error(
"Test failed to read proper array value.");
81 template<
typename arrayType,
typename iteratorType>
82 void runReadArrayTest()
86 const int setArrayLength = 10;
87 const int setArrayValue = 3;
88 for (
int testCycle = 0; testCycle < numTests; ++testCycle) {
89 std::vector<std::thread> threads;
91 ThreadTestManager::s_bAllowThreadsToRun =
false;
95 rcp(
new Array<int>( setArrayLength, setArrayValue ));
97 for (
int i = 0; i < numThreads; ++i) {
98 threads.push_back(std::thread(
99 thread_reads_array<arrayType, iteratorType>,
100 array_rcp, setArrayValue));
103 ThreadTestManager::s_bAllowThreadsToRun =
true;
105 for (
unsigned int i = 0; i < threads.size(); ++i) {
108 convenience_log_progress(testCycle, numTests);
181 static void call_inserts_on_array(RCP<Array<int>> shared_array,
int setValue,
182 int maxArraySize,
int finishWhenThisThreadCountCompletes) {
183 while (!ThreadTestManager::s_bAllowThreadsToRun) {}
185 const int insertCount = maxArraySize - shared_array->size();
187 for (
int n = 0;
n < insertCount; ++
n) {
188 shared_array->push_back(setValue);
191 for (
int n = 0;
n < insertCount; ++
n) {
192 shared_array->pop_back();
194 if (ThreadTestManager::s_countCompletedThreads >=
195 finishWhenThisThreadCountCompletes) {
200 ++ThreadTestManager::s_countWritingThreadCycles;
211 static void scramble_memory(
int scrambleValue,
212 int finishWhenThisThreadCountCompletes) {
213 while (!ThreadTestManager::s_bAllowThreadsToRun) {}
220 #define ARRAY_SCRAMBLE_SIZE 100
221 int * tempPtrArray[ARRAY_SCRAMBLE_SIZE];
222 for (
int n = 0;
n < ARRAY_SCRAMBLE_SIZE; ++
n) {
223 int * pInt =
new int;
224 *pInt = scrambleValue;
225 tempPtrArray[
n] = pInt;
227 for (
int n = 0;
n < ARRAY_SCRAMBLE_SIZE; ++
n) {
228 delete tempPtrArray[
n];
230 if (ThreadTestManager::s_countCompletedThreads >=
231 finishWhenThisThreadCountCompletes) {
241 enum ArrayTest_Style {
244 ArrayTest_DoReadOperations,
248 ArrayTest_TriggerDanglingWithIteration,
252 ArrayTest_TriggerDanglingWithIterationFirstCycle
259 template<
class arrayType>
260 static void do_read_operations_on_array(RCP<arrayType> shared_array,
261 int setValue,
int scrambleValue, Cycle_Index_Tracker & index_tracker,
262 int maxArraySize, ArrayTest_Style arrayTestStyle) {
264 while (!ThreadTestManager::s_bAllowThreadsToRun) {}
270 for (cycle = 0; cycle < 10000; ++cycle) {
271 switch (arrayTestStyle) {
272 case ArrayTest_DoReadOperations:
278 int readValue = shared_array->at(0);
279 if( readValue != setValue ) {
283 if( readValue == scrambleValue) {
287 index_tracker.scambledMemory = cycle;
296 index_tracker.scambledMemory = cycle;
301 case ArrayTest_TriggerDanglingWithIteration:
318 iter < shared_array->end(); ++iter) {
325 case ArrayTest_TriggerDanglingWithIterationFirstCycle:
332 index_tracker.missedDanglingOnFirstCycle = cycle;
336 ++ThreadTestManager::s_countCompletedThreads;
347 int getReadWriteThreadCycles =
348 ThreadTestManager::s_countWritingThreadCycles;
353 while (ThreadTestManager::s_countWritingThreadCycles <
354 getReadWriteThreadCycles + 2) {
366 catch (DanglingReferenceError) {
368 index_tracker.danglingReference = cycle;
372 index_tracker.outOfRangeError = cycle;
374 catch (std::out_of_range) {
380 index_tracker.outOfRangeError = cycle;
385 ++ThreadTestManager::s_countCompletedThreads;
395 bool runArrayDanglingReferenceTest(
bool bUseConstVersion,
396 ArrayTest_Style arrayTestStyle ) {
406 const int setValue = 1;
414 const int scrambleValue = 12345;
418 const int maxArraySize = 100;
423 int countTotalTestRuns = 0;
426 int countDetectedDanglingReferences = 0;
429 int countMissedFirstCycleDanglers = 0;
434 int countScrambledMemoryEvents = 0;
439 int countOutOfRangeEvents = 0;
441 for (
int testCycle = 0; testCycle < numTests; ++testCycle) {
442 std::vector<std::thread> threads;
443 ThreadTestManager::s_bAllowThreadsToRun =
false;
444 ThreadTestManager::s_countCompletedThreads = 0;
445 ThreadTestManager::s_countWritingThreadCycles = 0;
449 int finishWhenThisThreadCountCompletes = numThreads - 2;
453 Cycle_Index_Tracker index_tracker[numThreads];
457 RCP<Array<int>> array_rcp =
rcp(
new Array<int>(1, setValue));
459 for (
int i = 0; i < numThreads; ++i) {
465 threads.push_back( std::thread(call_inserts_on_array, array_rcp,
466 setValue, maxArraySize, finishWhenThisThreadCountCompletes) );
473 threads.push_back( std::thread(scramble_memory, scrambleValue,
474 finishWhenThisThreadCountCompletes) );
479 ++countTotalTestRuns;
480 if (bUseConstVersion) {
481 threads.push_back( std::thread(
482 do_read_operations_on_array<
const Array<int> >, array_rcp,
483 setValue, scrambleValue, std::ref(index_tracker[i]),
484 maxArraySize, arrayTestStyle));
487 threads.push_back( std::thread(
488 do_read_operations_on_array< Array<int> >, array_rcp,
489 setValue, scrambleValue, std::ref(index_tracker[i]),
490 maxArraySize, arrayTestStyle));
497 ThreadTestManager::s_bAllowThreadsToRun =
true;
500 for (
unsigned int i = 0; i < threads.size(); ++i) {
505 for (
unsigned int i = 0; i < threads.size(); ++i) {
508 ++countDetectedDanglingReferences;
514 ++countScrambledMemoryEvents;
519 ++countOutOfRangeEvents;
525 if (arrayTestStyle == ArrayTest_TriggerDanglingWithIterationFirstCycle
527 ++countMissedFirstCycleDanglers;
530 convenience_log_progress(testCycle, numTests);
534 switch (arrayTestStyle) {
535 case ArrayTest_DoReadOperations:
545 std::cout <<
"Range Errors: " << countOutOfRangeEvents <<
546 " Scrambles: " << countScrambledMemoryEvents <<
" ";
549 case ArrayTest_TriggerDanglingWithIterationFirstCycle:
550 case ArrayTest_TriggerDanglingWithIteration:
554 std::cout <<
"Danglers: " << countDetectedDanglingReferences <<
" ";
562 bool bPassed_DetectDanglers = (arrayTestStyle != ArrayTest_DoReadOperations)
563 ? (countDetectedDanglingReferences == countTotalTestRuns) :
true;
569 bool bPassed_DetectDanglersFirstCycle = (countMissedFirstCycleDanglers == 0);
574 bool bPassed_CountOutOfRangeErrors =
575 (arrayTestStyle == ArrayTest_DoReadOperations) ?
576 (countOutOfRangeEvents != 0) : (countOutOfRangeEvents == 0);
583 if(
NUM_TESTS_TO_RUN < 1000 && arrayTestStyle == ArrayTest_DoReadOperations) {
584 if(countOutOfRangeEvents == 0) {
585 bPassed_CountOutOfRangeErrors =
true;
591 bool bPass = bPassed_DetectDanglersFirstCycle &&
592 bPassed_DetectDanglersFirstCycle && bPassed_CountOutOfRangeErrors;
595 std::cout << std::endl;
599 if (!bPassed_DetectDanglers) {
600 std::cout <<
"Test FAILED because it detected only " <<
601 countDetectedDanglingReferences <<
602 " Dangling References but should have detected " << countTotalTestRuns
606 if( !bPassed_DetectDanglersFirstCycle ) {
607 std::cout <<
"Test FAILED because it missed " <<
608 countMissedFirstCycleDanglers <<
609 " Dangling References but should have detected " << countTotalTestRuns
610 <<
" on the first cycle." << std::endl;
613 if( !bPassed_CountOutOfRangeErrors ) {
614 std::cout <<
"Test FAILED because it detected " <<
615 countOutOfRangeEvents <<
616 " out of range events but should have detected: "
617 << ( (arrayTestStyle == ArrayTest_DoReadOperations) ?
618 "More Than 0" :
"0" ) << std::endl;
649 bPass = runArrayDanglingReferenceTest(
false,
650 ArrayTest_DoReadOperations );
674 bPass = runArrayDanglingReferenceTest(
true,
675 ArrayTest_DoReadOperations );
702 bPass = runArrayDanglingReferenceTest(
false,
703 ArrayTest_TriggerDanglingWithIteration );
726 bPass = runArrayDanglingReferenceTest(
true,
727 ArrayTest_TriggerDanglingWithIteration );
754 bPass = runArrayDanglingReferenceTest(
false,
755 ArrayTest_TriggerDanglingWithIterationFirstCycle );
778 bPass = runArrayDanglingReferenceTest(
true,
779 ArrayTest_TriggerDanglingWithIterationFirstCycle );
785 #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...