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