blob: 034c5d912f953705926d5ea19961627966730db7 [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"
reed89889b62014-10-29 12:36:45 -07009#include "SkRunnable.h"
mtklein406654b2014-09-03 15:34:37 -070010#include "SkTaskGroup.h"
mtklein@google.com3a19fb52013-10-09 16:12:23 +000011#include "Test.h"
mtklein@google.com3a19fb52013-10-09 16:12:23 +000012
commit-bot@chromium.org1f81fd62013-10-23 14:44:08 +000013static void add_five(int* x) {
mtklein@google.com3a19fb52013-10-09 16:12:23 +000014 *x += 5;
15}
16
mtklein199ba8e2015-01-13 08:40:23 -080017SK_DECLARE_STATIC_ONCE(st_once);
mtklein@google.com3a19fb52013-10-09 16:12:23 +000018DEF_TEST(SkOnce_Singlethreaded, r) {
19 int x = 0;
20
21 // No matter how many times we do this, x will be 5.
mtklein199ba8e2015-01-13 08:40:23 -080022 SkOnce(&st_once, add_five, &x);
23 SkOnce(&st_once, add_five, &x);
24 SkOnce(&st_once, add_five, &x);
25 SkOnce(&st_once, add_five, &x);
26 SkOnce(&st_once, add_five, &x);
mtklein@google.com3a19fb52013-10-09 16:12:23 +000027
28 REPORTER_ASSERT(r, 5 == x);
29}
30
commit-bot@chromium.org1f81fd62013-10-23 14:44:08 +000031static void add_six(int* x) {
mtklein@google.com3a19fb52013-10-09 16:12:23 +000032 *x += 6;
33}
34
mtklein1d932662014-10-20 13:46:11 -070035namespace {
36
mtklein@google.com3a19fb52013-10-09 16:12:23 +000037class Racer : public SkRunnable {
38public:
commit-bot@chromium.org1f81fd62013-10-23 14:44:08 +000039 SkOnceFlag* once;
mtklein@google.com3a19fb52013-10-09 16:12:23 +000040 int* ptr;
commit-bot@chromium.org1f81fd62013-10-23 14:44:08 +000041
mtklein36352bf2015-03-25 18:17:31 -070042 void run() override {
commit-bot@chromium.org1f81fd62013-10-23 14:44:08 +000043 SkOnce(once, add_six, ptr);
mtklein@google.com3a19fb52013-10-09 16:12:23 +000044 }
45};
46
mtklein1d932662014-10-20 13:46:11 -070047} // namespace
48
mtklein199ba8e2015-01-13 08:40:23 -080049SK_DECLARE_STATIC_ONCE(mt_once);
mtklein@google.com3a19fb52013-10-09 16:12:23 +000050DEF_TEST(SkOnce_Multithreaded, r) {
mtklein406654b2014-09-03 15:34:37 -070051 const int kTasks = 16;
mtklein@google.com3a19fb52013-10-09 16:12:23 +000052
53 // Make a bunch of tasks that will race to be the first to add six to x.
54 Racer racers[kTasks];
55 int x = 0;
56 for (int i = 0; i < kTasks; i++) {
mtklein199ba8e2015-01-13 08:40:23 -080057 racers[i].once = &mt_once;
mtklein@google.com3a19fb52013-10-09 16:12:23 +000058 racers[i].ptr = &x;
59 }
60
61 // Let them race.
mtklein406654b2014-09-03 15:34:37 -070062 SkTaskGroup tg;
mtklein@google.com3a19fb52013-10-09 16:12:23 +000063 for (int i = 0; i < kTasks; i++) {
mtklein406654b2014-09-03 15:34:37 -070064 tg.add(&racers[i]);
mtklein@google.com3a19fb52013-10-09 16:12:23 +000065 }
mtklein406654b2014-09-03 15:34:37 -070066 tg.wait();
mtklein@google.com3a19fb52013-10-09 16:12:23 +000067
68 // Only one should have done the +=.
69 REPORTER_ASSERT(r, 6 == x);
70}
commit-bot@chromium.org709ca752014-01-24 22:38:39 +000071
mtklein1b818772014-06-02 11:26:59 -070072static int gX = 0;
73static void inc_gX() { gX++; }
commit-bot@chromium.org709ca752014-01-24 22:38:39 +000074
mtklein199ba8e2015-01-13 08:40:23 -080075SK_DECLARE_STATIC_ONCE(noarg_once);
mtklein1b818772014-06-02 11:26:59 -070076DEF_TEST(SkOnce_NoArg, r) {
mtklein199ba8e2015-01-13 08:40:23 -080077 SkOnce(&noarg_once, inc_gX);
78 SkOnce(&noarg_once, inc_gX);
79 SkOnce(&noarg_once, inc_gX);
mtklein1b818772014-06-02 11:26:59 -070080 REPORTER_ASSERT(r, 1 == gX);
commit-bot@chromium.org709ca752014-01-24 22:38:39 +000081}