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 12 static void add_five(int* x) { 13 *x += 5; 14 } 15 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 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 39 virtual void run() SK_OVERRIDE { 40 SkOnce(once, add_six, ptr); 41 } 42 }; 43 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; 68 static void inc_gX() { gX++; } 69 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