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