Home | History | Annotate | Download | only in tests
      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