1 /*
2 * Copyright 2013 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 "SkOnce.h"
9 #include "SkThreadPool.h"
10 #include "Test.h"
11
add_five(int * x)12 static void add_five(int* x) {
13 *x += 5;
14 }
15
DEF_TEST(SkOnce_Singlethreaded,r)16 DEF_TEST(SkOnce_Singlethreaded, r) {
17 int x = 0;
18
19 SK_DECLARE_STATIC_ONCE(once);
20 // No matter how many times we do this, x will be 5.
21 SkOnce(&once, add_five, &x);
22 SkOnce(&once, add_five, &x);
23 SkOnce(&once, add_five, &x);
24 SkOnce(&once, add_five, &x);
25 SkOnce(&once, add_five, &x);
26
27 REPORTER_ASSERT(r, 5 == x);
28 }
29
add_six(int * x)30 static void add_six(int* x) {
31 *x += 6;
32 }
33
34 class Racer : public SkRunnable {
35 public:
36 SkOnceFlag* once;
37 int* ptr;
38
run()39 virtual void run() SK_OVERRIDE {
40 SkOnce(once, add_six, ptr);
41 }
42 };
43
DEF_TEST(SkOnce_Multithreaded,r)44 DEF_TEST(SkOnce_Multithreaded, r) {
45 const int kTasks = 16, kThreads = 4;
46
47 // Make a bunch of tasks that will race to be the first to add six to x.
48 Racer racers[kTasks];
49 SK_DECLARE_STATIC_ONCE(once);
50 int x = 0;
51 for (int i = 0; i < kTasks; i++) {
52 racers[i].once = &once;
53 racers[i].ptr = &x;
54 }
55
56 // Let them race.
57 SkThreadPool pool(kThreads);
58 for (int i = 0; i < kTasks; i++) {
59 pool.add(&racers[i]);
60 }
61 pool.wait();
62
63 // Only one should have done the +=.
64 REPORTER_ASSERT(r, 6 == x);
65 }
66
67 static int gX = 0;
inc_gX()68 static void inc_gX() { gX++; }
69
DEF_TEST(SkOnce_NoArg,r)70 DEF_TEST(SkOnce_NoArg, r) {
71 SK_DECLARE_STATIC_ONCE(once);
72 SkOnce(&once, inc_gX);
73 SkOnce(&once, inc_gX);
74 SkOnce(&once, inc_gX);
75 REPORTER_ASSERT(r, 1 == gX);
76 }
77