/* * Copyright 2013 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "SkOnce.h" #include "SkRunnable.h" #include "SkTaskGroup.h" #include "Test.h" static void add_five(int* x) { *x += 5; } SK_DECLARE_STATIC_ONCE(st_once); DEF_TEST(SkOnce_Singlethreaded, r) { int x = 0; // No matter how many times we do this, x will be 5. SkOnce(&st_once, add_five, &x); SkOnce(&st_once, add_five, &x); SkOnce(&st_once, add_five, &x); SkOnce(&st_once, add_five, &x); SkOnce(&st_once, add_five, &x); REPORTER_ASSERT(r, 5 == x); } static void add_six(int* x) { *x += 6; } namespace { class Racer : public SkRunnable { public: SkOnceFlag* once; int* ptr; void run() override { SkOnce(once, add_six, ptr); } }; } // namespace SK_DECLARE_STATIC_ONCE(mt_once); DEF_TEST(SkOnce_Multithreaded, r) { const int kTasks = 16; // Make a bunch of tasks that will race to be the first to add six to x. Racer racers[kTasks]; int x = 0; for (int i = 0; i < kTasks; i++) { racers[i].once = &mt_once; racers[i].ptr = &x; } // Let them race. SkTaskGroup tg; for (int i = 0; i < kTasks; i++) { tg.add(&racers[i]); } tg.wait(); // Only one should have done the +=. REPORTER_ASSERT(r, 6 == x); } static int gX = 0; static void inc_gX() { gX++; } SK_DECLARE_STATIC_ONCE(noarg_once); DEF_TEST(SkOnce_NoArg, r) { SkOnce(&noarg_once, inc_gX); SkOnce(&noarg_once, inc_gX); SkOnce(&noarg_once, inc_gX); REPORTER_ASSERT(r, 1 == gX); }