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 "SkTaskGroup.h" 10#include "Test.h" 11 12static void add_five(int* x) { 13 *x += 5; 14} 15 16DEF_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 30static void add_six(int* x) { 31 *x += 6; 32} 33 34class Racer : public SkRunnable { 35public: 36 SkOnceFlag* once; 37 int* ptr; 38 39 virtual void run() SK_OVERRIDE { 40 SkOnce(once, add_six, ptr); 41 } 42}; 43 44DEF_TEST(SkOnce_Multithreaded, r) { 45 const int kTasks = 16; 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 SkTaskGroup tg; 58 for (int i = 0; i < kTasks; i++) { 59 tg.add(&racers[i]); 60 } 61 tg.wait(); 62 63 // Only one should have done the +=. 64 REPORTER_ASSERT(r, 6 == x); 65} 66 67static int gX = 0; 68static void inc_gX() { gX++; } 69 70DEF_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