Home | History | Annotate | Download | only in tests
      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 #include "TestClassDef.h"
     12 
     13 static void add_five(int* x) {
     14     *x += 5;
     15 }
     16 
     17 DEF_TEST(SkOnce_Singlethreaded, r) {
     18     int x = 0;
     19 
     20     SK_DECLARE_STATIC_ONCE(once);
     21     // No matter how many times we do this, x will be 5.
     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     SkOnce(&once, add_five, &x);
     27 
     28     REPORTER_ASSERT(r, 5 == x);
     29 }
     30 
     31 struct AddFour { void operator()(int* x) { *x += 4; } };
     32 
     33 DEF_TEST(SkOnce_MiscFeatures, r) {
     34     // Tests that we support functors and explicit SkOnceFlags.
     35     int x = 0;
     36 
     37     SkOnceFlag once = SK_ONCE_INIT;
     38     SkOnce(&once, AddFour(), &x);
     39     SkOnce(&once, AddFour(), &x);
     40     SkOnce(&once, AddFour(), &x);
     41 
     42     REPORTER_ASSERT(r, 4 == x);
     43 }
     44 
     45 static void add_six(int* x) {
     46     *x += 6;
     47 }
     48 
     49 class Racer : public SkRunnable {
     50 public:
     51     SkOnceFlag* once;
     52     int* ptr;
     53 
     54     virtual void run() SK_OVERRIDE {
     55         SkOnce(once, add_six, ptr);
     56     }
     57 };
     58 
     59 DEF_TEST(SkOnce_Multithreaded, r) {
     60     const int kTasks = 16, kThreads = 4;
     61 
     62     // Make a bunch of tasks that will race to be the first to add six to x.
     63     Racer racers[kTasks];
     64     SK_DECLARE_STATIC_ONCE(once);
     65     int x = 0;
     66     for (int i = 0; i < kTasks; i++) {
     67         racers[i].once = &once;
     68         racers[i].ptr = &x;
     69     }
     70 
     71     // Let them race.
     72     SkThreadPool pool(kThreads);
     73     for (int i = 0; i < kTasks; i++) {
     74         pool.add(&racers[i]);
     75     }
     76     pool.wait();
     77 
     78     // Only one should have done the +=.
     79     REPORTER_ASSERT(r, 6 == x);
     80 }
     81