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 "SkThreadUtils.h"
10 #include "SkTypes.h"
11 #include "SkWeakRefCnt.h"
12 #include "Test.h"
13 
bounce_ref(void * data)14 static void bounce_ref(void* data) {
15     SkRefCnt* ref = static_cast<SkRefCnt*>(data);
16     for (int i = 0; i < 100000; ++i) {
17         ref->ref();
18         ref->unref();
19     }
20 }
21 
test_refCnt(skiatest::Reporter * reporter)22 static void test_refCnt(skiatest::Reporter* reporter) {
23     SkRefCnt* ref = new SkRefCnt();
24 
25     SkThread thing1(bounce_ref, ref);
26     SkThread thing2(bounce_ref, ref);
27 
28     thing1.setProcessorAffinity(0);
29     thing2.setProcessorAffinity(23);
30 
31     SkASSERT(thing1.start());
32     SkASSERT(thing2.start());
33 
34     thing1.join();
35     thing2.join();
36 
37     REPORTER_ASSERT(reporter, ref->unique());
38     ref->unref();
39 }
40 
bounce_weak_ref(void * data)41 static void bounce_weak_ref(void* data) {
42     SkWeakRefCnt* ref = static_cast<SkWeakRefCnt*>(data);
43     for (int i = 0; i < 100000; ++i) {
44         if (ref->try_ref()) {
45             ref->unref();
46         }
47     }
48 }
49 
bounce_weak_weak_ref(void * data)50 static void bounce_weak_weak_ref(void* data) {
51     SkWeakRefCnt* ref = static_cast<SkWeakRefCnt*>(data);
52     for (int i = 0; i < 100000; ++i) {
53         ref->weak_ref();
54         ref->weak_unref();
55     }
56 }
57 
test_weakRefCnt(skiatest::Reporter * reporter)58 static void test_weakRefCnt(skiatest::Reporter* reporter) {
59     SkWeakRefCnt* ref = new SkWeakRefCnt();
60 
61     SkThread thing1(bounce_ref, ref);
62     SkThread thing2(bounce_ref, ref);
63     SkThread thing3(bounce_weak_ref, ref);
64     SkThread thing4(bounce_weak_weak_ref, ref);
65 
66     thing1.setProcessorAffinity(0);
67     thing2.setProcessorAffinity(23);
68     thing3.setProcessorAffinity(2);
69     thing4.setProcessorAffinity(17);
70 
71     SkASSERT(thing1.start());
72     SkASSERT(thing2.start());
73     SkASSERT(thing3.start());
74     SkASSERT(thing4.start());
75 
76     thing1.join();
77     thing2.join();
78     thing3.join();
79     thing4.join();
80 
81     REPORTER_ASSERT(reporter, ref->unique());
82     REPORTER_ASSERT(reporter, ref->getWeakCnt() == 1);
83     ref->unref();
84 }
85 
DEF_TEST(RefCnt,reporter)86 DEF_TEST(RefCnt, reporter) {
87     test_refCnt(reporter);
88     test_weakRefCnt(reporter);
89 }
90