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 "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