blob: 0b2aa9a8571a3e2bcbe44d014b969bb363c3da1f [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"
9#include "SkRunnable.h"
10#include "SkThreadPool.h"
11#include "Test.h"
12#include "TestClassDef.h"
13
14DEF_SK_ONCE(add_five, int* x) {
15 *x += 5;
16}
17
18DEF_TEST(SkOnce_Singlethreaded, r) {
19 int x = 0;
20
21 // No matter how many times we do this, x will be 5.
22 SK_ONCE(add_five, &x);
23 SK_ONCE(add_five, &x);
24 SK_ONCE(add_five, &x);
25 SK_ONCE(add_five, &x);
26 SK_ONCE(add_five, &x);
27
28 REPORTER_ASSERT(r, 5 == x);
29}
30
31
32DEF_SK_ONCE(add_six, int* x) {
33 *x += 6;
34}
35
36namespace {
37
38class Racer : public SkRunnable {
39public:
40 int* ptr;
41 virtual void run() SK_OVERRIDE {
42 SK_ONCE(add_six, ptr);
43 }
44};
45
46} // namespace
47
48DEF_TEST(SkOnce_Multithreaded, r) {
49 const int kTasks = 16, kThreads = 4;
50
51 // Make a bunch of tasks that will race to be the first to add six to x.
52 Racer racers[kTasks];
53 int x = 0;
54 for (int i = 0; i < kTasks; i++) {
55 racers[i].ptr = &x;
56 }
57
58 // Let them race.
59 SkAutoTDelete<SkThreadPool> pool(new SkThreadPool(kThreads));
60 for (int i = 0; i < kTasks; i++) {
61 pool->add(&racers[i]);
62 }
63 pool.free(); // Blocks until all threads are done.
64
65 // Only one should have done the +=.
66 REPORTER_ASSERT(r, 6 == x);
67}