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