/* * Copyright 2012 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "SkTypes.h" #include "Test.h" #include "SkRefCnt.h" #include "SkThreadUtils.h" #include "SkWeakRefCnt.h" #include "SkTRefArray.h" /////////////////////////////////////////////////////////////////////////////// class InstCounterClass { public: InstCounterClass() { fCount = gInstCounter++; } InstCounterClass(const InstCounterClass& src) { fCount = src.fCount; gInstCounter += 1; } virtual ~InstCounterClass() { gInstCounter -= 1; } static int gInstCounter; int fCount; }; int InstCounterClass::gInstCounter; static void test_refarray(skiatest::Reporter* reporter) { REPORTER_ASSERT(reporter, 0 == InstCounterClass::gInstCounter); const int N = 10; SkTRefArray<InstCounterClass>* array = SkTRefArray<InstCounterClass>::Create(N); REPORTER_ASSERT(reporter, 1 == array->getRefCnt()); REPORTER_ASSERT(reporter, N == array->count()); REPORTER_ASSERT(reporter, N == InstCounterClass::gInstCounter); array->unref(); REPORTER_ASSERT(reporter, 0 == InstCounterClass::gInstCounter); // Now test the copy factory int i; InstCounterClass* src = new InstCounterClass[N]; REPORTER_ASSERT(reporter, N == InstCounterClass::gInstCounter); for (i = 0; i < N; ++i) { REPORTER_ASSERT(reporter, i == src[i].fCount); } array = SkTRefArray<InstCounterClass>::Create(src, N); REPORTER_ASSERT(reporter, 1 == array->getRefCnt()); REPORTER_ASSERT(reporter, N == array->count()); REPORTER_ASSERT(reporter, 2*N == InstCounterClass::gInstCounter); for (i = 0; i < N; ++i) { REPORTER_ASSERT(reporter, i == (*array)[i].fCount); } delete[] src; REPORTER_ASSERT(reporter, N == InstCounterClass::gInstCounter); for (i = 0; i < N; ++i) { REPORTER_ASSERT(reporter, i == (*array)[i].fCount); } array->unref(); REPORTER_ASSERT(reporter, 0 == InstCounterClass::gInstCounter); } static void bounce_ref(void* data) { SkRefCnt* ref = static_cast<SkRefCnt*>(data); for (int i = 0; i < 100000; ++i) { ref->ref(); ref->unref(); } } static void test_refCnt(skiatest::Reporter* reporter) { SkRefCnt* ref = new SkRefCnt(); SkThread thing1(bounce_ref, ref); SkThread thing2(bounce_ref, ref); thing1.setProcessorAffinity(0); thing2.setProcessorAffinity(23); SkASSERT(thing1.start()); SkASSERT(thing2.start()); thing1.join(); thing2.join(); REPORTER_ASSERT(reporter, ref->getRefCnt() == 1); ref->unref(); } static void bounce_weak_ref(void* data) { SkWeakRefCnt* ref = static_cast<SkWeakRefCnt*>(data); for (int i = 0; i < 100000; ++i) { if (ref->try_ref()) { ref->unref(); } } } static void bounce_weak_weak_ref(void* data) { SkWeakRefCnt* ref = static_cast<SkWeakRefCnt*>(data); for (int i = 0; i < 100000; ++i) { ref->weak_ref(); ref->weak_unref(); } } static void test_weakRefCnt(skiatest::Reporter* reporter) { SkWeakRefCnt* ref = new SkWeakRefCnt(); SkThread thing1(bounce_ref, ref); SkThread thing2(bounce_ref, ref); SkThread thing3(bounce_weak_ref, ref); SkThread thing4(bounce_weak_weak_ref, ref); thing1.setProcessorAffinity(0); thing2.setProcessorAffinity(23); thing3.setProcessorAffinity(2); thing4.setProcessorAffinity(17); SkASSERT(thing1.start()); SkASSERT(thing2.start()); SkASSERT(thing3.start()); SkASSERT(thing4.start()); thing1.join(); thing2.join(); thing3.join(); thing4.join(); REPORTER_ASSERT(reporter, ref->getRefCnt() == 1); REPORTER_ASSERT(reporter, ref->getWeakCnt() == 1); ref->unref(); } static void test_refCntTests(skiatest::Reporter* reporter) { test_refCnt(reporter); test_weakRefCnt(reporter); test_refarray(reporter); } #include "TestClassDef.h" DEFINE_TESTCLASS("RefCnt", RefCntTestClass, test_refCntTests)