• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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