1 /* 2 * Copyright 2012 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "SkTypes.h" 9 #include "Test.h" 10 11 #include "SkRefCnt.h" 12 #include "SkThreadUtils.h" 13 #include "SkWeakRefCnt.h" 14 #include "SkTRefArray.h" 15 16 /////////////////////////////////////////////////////////////////////////////// 17 18 class InstCounterClass { 19 public: 20 InstCounterClass() { fCount = gInstCounter++; } 21 InstCounterClass(const InstCounterClass& src) { 22 fCount = src.fCount; 23 gInstCounter += 1; 24 } 25 virtual ~InstCounterClass() { gInstCounter -= 1; } 26 27 static int gInstCounter; 28 int fCount; 29 }; 30 31 int InstCounterClass::gInstCounter; 32 33 static void test_refarray(skiatest::Reporter* reporter) { 34 REPORTER_ASSERT(reporter, 0 == InstCounterClass::gInstCounter); 35 36 const int N = 10; 37 SkTRefArray<InstCounterClass>* array = SkTRefArray<InstCounterClass>::Create(N); 38 39 REPORTER_ASSERT(reporter, 1 == array->getRefCnt()); 40 REPORTER_ASSERT(reporter, N == array->count()); 41 42 REPORTER_ASSERT(reporter, N == InstCounterClass::gInstCounter); 43 array->unref(); 44 REPORTER_ASSERT(reporter, 0 == InstCounterClass::gInstCounter); 45 46 // Now test the copy factory 47 48 int i; 49 InstCounterClass* src = new InstCounterClass[N]; 50 REPORTER_ASSERT(reporter, N == InstCounterClass::gInstCounter); 51 for (i = 0; i < N; ++i) { 52 REPORTER_ASSERT(reporter, i == src[i].fCount); 53 } 54 55 array = SkTRefArray<InstCounterClass>::Create(src, N); 56 REPORTER_ASSERT(reporter, 1 == array->getRefCnt()); 57 REPORTER_ASSERT(reporter, N == array->count()); 58 59 REPORTER_ASSERT(reporter, 2*N == InstCounterClass::gInstCounter); 60 for (i = 0; i < N; ++i) { 61 REPORTER_ASSERT(reporter, i == (*array)[i].fCount); 62 } 63 64 delete[] src; 65 REPORTER_ASSERT(reporter, N == InstCounterClass::gInstCounter); 66 67 for (i = 0; i < N; ++i) { 68 REPORTER_ASSERT(reporter, i == (*array)[i].fCount); 69 } 70 array->unref(); 71 REPORTER_ASSERT(reporter, 0 == InstCounterClass::gInstCounter); 72 } 73 74 static void bounce_ref(void* data) { 75 SkRefCnt* ref = static_cast<SkRefCnt*>(data); 76 for (int i = 0; i < 100000; ++i) { 77 ref->ref(); 78 ref->unref(); 79 } 80 } 81 82 static void test_refCnt(skiatest::Reporter* reporter) { 83 SkRefCnt* ref = new SkRefCnt(); 84 85 SkThread thing1(bounce_ref, ref); 86 SkThread thing2(bounce_ref, ref); 87 88 thing1.setProcessorAffinity(0); 89 thing2.setProcessorAffinity(23); 90 91 SkASSERT(thing1.start()); 92 SkASSERT(thing2.start()); 93 94 thing1.join(); 95 thing2.join(); 96 97 REPORTER_ASSERT(reporter, ref->getRefCnt() == 1); 98 ref->unref(); 99 } 100 101 static void bounce_weak_ref(void* data) { 102 SkWeakRefCnt* ref = static_cast<SkWeakRefCnt*>(data); 103 for (int i = 0; i < 100000; ++i) { 104 if (ref->try_ref()) { 105 ref->unref(); 106 } 107 } 108 } 109 110 static void bounce_weak_weak_ref(void* data) { 111 SkWeakRefCnt* ref = static_cast<SkWeakRefCnt*>(data); 112 for (int i = 0; i < 100000; ++i) { 113 ref->weak_ref(); 114 ref->weak_unref(); 115 } 116 } 117 118 static void test_weakRefCnt(skiatest::Reporter* reporter) { 119 SkWeakRefCnt* ref = new SkWeakRefCnt(); 120 121 SkThread thing1(bounce_ref, ref); 122 SkThread thing2(bounce_ref, ref); 123 SkThread thing3(bounce_weak_ref, ref); 124 SkThread thing4(bounce_weak_weak_ref, ref); 125 126 thing1.setProcessorAffinity(0); 127 thing2.setProcessorAffinity(23); 128 thing3.setProcessorAffinity(2); 129 thing4.setProcessorAffinity(17); 130 131 SkASSERT(thing1.start()); 132 SkASSERT(thing2.start()); 133 SkASSERT(thing3.start()); 134 SkASSERT(thing4.start()); 135 136 thing1.join(); 137 thing2.join(); 138 thing3.join(); 139 thing4.join(); 140 141 REPORTER_ASSERT(reporter, ref->getRefCnt() == 1); 142 REPORTER_ASSERT(reporter, ref->getWeakCnt() == 1); 143 ref->unref(); 144 } 145 146 static void test_refCntTests(skiatest::Reporter* reporter) { 147 test_refCnt(reporter); 148 test_weakRefCnt(reporter); 149 test_refarray(reporter); 150 } 151 152 #include "TestClassDef.h" 153 DEFINE_TESTCLASS("RefCnt", RefCntTestClass, test_refCntTests) 154