blob: 3a99c39d5396f82fc1d2b770425cc032ee6ca064 [file] [log] [blame]
mtklein@google.com3a19fb52013-10-09 16:12:23 +00001/*
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"
mtklein@google.com3a19fb52013-10-09 16:12:23 +00009#include "SkThreadPool.h"
10#include "Test.h"
mtklein@google.com3a19fb52013-10-09 16:12:23 +000011
commit-bot@chromium.org1f81fd62013-10-23 14:44:08 +000012static void add_five(int* x) {
mtklein@google.com3a19fb52013-10-09 16:12:23 +000013 *x += 5;
14}
15
16DEF_TEST(SkOnce_Singlethreaded, r) {
17 int x = 0;
18
commit-bot@chromium.org1f81fd62013-10-23 14:44:08 +000019 SK_DECLARE_STATIC_ONCE(once);
mtklein@google.com3a19fb52013-10-09 16:12:23 +000020 // No matter how many times we do this, x will be 5.
commit-bot@chromium.org1f81fd62013-10-23 14:44:08 +000021 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);
mtklein@google.com3a19fb52013-10-09 16:12:23 +000026
27 REPORTER_ASSERT(r, 5 == x);
28}
29
commit-bot@chromium.org1b2c1b82013-12-05 19:20:49 +000030struct AddFour { void operator()(int* x) { *x += 4; } };
31
32DEF_TEST(SkOnce_MiscFeatures, r) {
33 // Tests that we support functors and explicit SkOnceFlags.
34 int x = 0;
35
36 SkOnceFlag once = SK_ONCE_INIT;
37 SkOnce(&once, AddFour(), &x);
38 SkOnce(&once, AddFour(), &x);
39 SkOnce(&once, AddFour(), &x);
40
41 REPORTER_ASSERT(r, 4 == x);
42}
43
commit-bot@chromium.org1f81fd62013-10-23 14:44:08 +000044static void add_six(int* x) {
mtklein@google.com3a19fb52013-10-09 16:12:23 +000045 *x += 6;
46}
47
mtklein@google.com3a19fb52013-10-09 16:12:23 +000048class Racer : public SkRunnable {
49public:
commit-bot@chromium.org1f81fd62013-10-23 14:44:08 +000050 SkOnceFlag* once;
mtklein@google.com3a19fb52013-10-09 16:12:23 +000051 int* ptr;
commit-bot@chromium.org1f81fd62013-10-23 14:44:08 +000052
mtklein@google.com3a19fb52013-10-09 16:12:23 +000053 virtual void run() SK_OVERRIDE {
commit-bot@chromium.org1f81fd62013-10-23 14:44:08 +000054 SkOnce(once, add_six, ptr);
mtklein@google.com3a19fb52013-10-09 16:12:23 +000055 }
56};
57
mtklein@google.com3a19fb52013-10-09 16:12:23 +000058DEF_TEST(SkOnce_Multithreaded, r) {
59 const int kTasks = 16, kThreads = 4;
60
61 // Make a bunch of tasks that will race to be the first to add six to x.
62 Racer racers[kTasks];
commit-bot@chromium.org1f81fd62013-10-23 14:44:08 +000063 SK_DECLARE_STATIC_ONCE(once);
mtklein@google.com3a19fb52013-10-09 16:12:23 +000064 int x = 0;
65 for (int i = 0; i < kTasks; i++) {
commit-bot@chromium.org1f81fd62013-10-23 14:44:08 +000066 racers[i].once = &once;
mtklein@google.com3a19fb52013-10-09 16:12:23 +000067 racers[i].ptr = &x;
68 }
69
70 // Let them race.
commit-bot@chromium.orga7538ba2013-10-10 18:49:04 +000071 SkThreadPool pool(kThreads);
mtklein@google.com3a19fb52013-10-09 16:12:23 +000072 for (int i = 0; i < kTasks; i++) {
commit-bot@chromium.orga7538ba2013-10-10 18:49:04 +000073 pool.add(&racers[i]);
mtklein@google.com3a19fb52013-10-09 16:12:23 +000074 }
commit-bot@chromium.orga7538ba2013-10-10 18:49:04 +000075 pool.wait();
mtklein@google.com3a19fb52013-10-09 16:12:23 +000076
77 // Only one should have done the +=.
78 REPORTER_ASSERT(r, 6 == x);
79}
commit-bot@chromium.org709ca752014-01-24 22:38:39 +000080
81// Test that the atExit option works.
82static int gToDecrement = 1;
83static void noop(int) {}
84static void decrement() { gToDecrement--; }
85static void checkDecremented() { SkASSERT(gToDecrement == 0); }
86
87DEF_TEST(SkOnce_atExit, r) {
88 atexit(checkDecremented);
89 SK_DECLARE_STATIC_ONCE(once);
90 SkOnce(&once, noop, 0, decrement);
91}