blob: 31c6a85a44cbd50213129f3c265ae8c71773cf55 [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"
11#include "TestClassDef.h"
12
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
17DEF_TEST(SkOnce_Singlethreaded, r) {
18 int x = 0;
19
commit-bot@chromium.org1f81fd62013-10-23 14:44:08 +000020 SK_DECLARE_STATIC_ONCE(once);
mtklein@google.com3a19fb52013-10-09 16:12:23 +000021 // No matter how many times we do this, x will be 5.
commit-bot@chromium.org1f81fd62013-10-23 14:44:08 +000022 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);
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
mtklein@google.com3a19fb52013-10-09 16:12:23 +000035class Racer : public SkRunnable {
36public:
commit-bot@chromium.org1f81fd62013-10-23 14:44:08 +000037 SkOnceFlag* once;
mtklein@google.com3a19fb52013-10-09 16:12:23 +000038 int* ptr;
commit-bot@chromium.org1f81fd62013-10-23 14:44:08 +000039
mtklein@google.com3a19fb52013-10-09 16:12:23 +000040 virtual void run() SK_OVERRIDE {
commit-bot@chromium.org1f81fd62013-10-23 14:44:08 +000041 SkOnce(once, add_six, ptr);
mtklein@google.com3a19fb52013-10-09 16:12:23 +000042 }
43};
44
mtklein@google.com3a19fb52013-10-09 16:12:23 +000045DEF_TEST(SkOnce_Multithreaded, r) {
46 const int kTasks = 16, kThreads = 4;
47
48 // Make a bunch of tasks that will race to be the first to add six to x.
49 Racer racers[kTasks];
commit-bot@chromium.org1f81fd62013-10-23 14:44:08 +000050 SK_DECLARE_STATIC_ONCE(once);
mtklein@google.com3a19fb52013-10-09 16:12:23 +000051 int x = 0;
52 for (int i = 0; i < kTasks; i++) {
commit-bot@chromium.org1f81fd62013-10-23 14:44:08 +000053 racers[i].once = &once;
mtklein@google.com3a19fb52013-10-09 16:12:23 +000054 racers[i].ptr = &x;
55 }
56
57 // Let them race.
commit-bot@chromium.orga7538ba2013-10-10 18:49:04 +000058 SkThreadPool pool(kThreads);
mtklein@google.com3a19fb52013-10-09 16:12:23 +000059 for (int i = 0; i < kTasks; i++) {
commit-bot@chromium.orga7538ba2013-10-10 18:49:04 +000060 pool.add(&racers[i]);
mtklein@google.com3a19fb52013-10-09 16:12:23 +000061 }
commit-bot@chromium.orga7538ba2013-10-10 18:49:04 +000062 pool.wait();
mtklein@google.com3a19fb52013-10-09 16:12:23 +000063
64 // Only one should have done the +=.
65 REPORTER_ASSERT(r, 6 == x);
66}