Speed up Heap::isMarkedConcurrently
[WebKit-https.git] / Tools / TestWebKitAPI / Tests / WTF / Consume.cpp
1 /*
2  * Copyright (C) 2016 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27
28 #include <thread>
29 #include <wtf/Atomics.h>
30
31 template <typename T>
32 NEVER_INLINE auto testConsume(const T* location)
33 {
34     WTF::compilerFence(); // Paranoid testing.
35     auto ret = WTF::consumeLoad(location);
36     WTF::compilerFence(); // Paranoid testing.
37     return ret;
38 }
39
40 namespace TestWebKitAPI {
41
42 TEST(WTF, Consumei8)
43 {
44     uint8_t i8 = 42;
45     auto i8_consumed = testConsume(&i8);
46     ASSERT_EQ(i8_consumed.value, 42u);
47     ASSERT_EQ(i8_consumed.dependency, 0u);
48 }
49
50 TEST(WTF, Consumei16)
51 {
52     uint16_t i16 = 42;
53     auto i16_consumed = testConsume(&i16);
54     ASSERT_EQ(i16_consumed.value, 42u);
55     ASSERT_EQ(i16_consumed.dependency, 0u);
56 }
57
58 TEST(WTF, Consumei32)
59 {
60     uint32_t i32 = 42;
61     auto i32_consumed = testConsume(&i32);
62     ASSERT_EQ(i32_consumed.value, 42u);
63     ASSERT_EQ(i32_consumed.dependency, 0u);
64 }
65
66 TEST(WTF, Consumei64)
67 {
68     uint64_t i64 = 42;
69     auto i64_consumed = testConsume(&i64);
70     ASSERT_EQ(i64_consumed.value, 42u);
71     ASSERT_EQ(i64_consumed.dependency, 0u);
72 }
73
74 TEST(WTF, Consumef32)
75 {
76     float f32 = 42.f;
77     auto f32_consumed = testConsume(&f32);
78     ASSERT_EQ(f32_consumed.value, 42.f);
79     ASSERT_EQ(f32_consumed.dependency, 0u);
80 }
81
82 TEST(WTF, Consumef64)
83 {
84     double f64 = 42.;
85     auto f64_consumed = testConsume(&f64);
86     ASSERT_EQ(f64_consumed.value, 42.);
87     ASSERT_EQ(f64_consumed.dependency, 0u);
88 }
89
90 static int* global;
91
92 TEST(WTF, ConsumeGlobalPtr)
93 {
94     auto* ptr = &global;
95     auto ptr_consumed = testConsume(&ptr);
96     ASSERT_EQ(ptr_consumed.value, &global);
97     ASSERT_EQ(ptr_consumed.dependency, 0u);
98 }
99
100 static int* globalArray[128];
101
102 TEST(WTF, ConsumeGlobalArrayPtr)
103 {
104     auto* ptr = &globalArray[64];
105     auto ptr_consumed = testConsume(&ptr);
106     ASSERT_EQ(ptr_consumed.value, &globalArray[64]);
107     ASSERT_EQ(ptr_consumed.dependency, 0u);
108 }
109
110 TEST(WTF, ConsumeStackPtr)
111 {
112     char* hello = nullptr;
113     auto* stack = &hello;
114     auto stack_consumed = testConsume(&stack);
115     ASSERT_EQ(stack_consumed.value, &hello);
116     ASSERT_EQ(stack_consumed.dependency, 0u);
117 }
118
119 TEST(WTF, ConsumeWithThread)
120 {
121     bool ready = false;
122     constexpr size_t num = 1024;
123     uint32_t* vec = new uint32_t[num];
124     std::thread t([&]() {
125         for (size_t i = 0; i != num; ++i)
126             vec[i] = i * 2;
127         WTF::storeStoreFence();
128         ready = true;
129     });
130     do {
131         auto stack_consumed = testConsume(&ready);
132         if (stack_consumed.value) {
133             for (size_t i = 0; i != num; ++i)
134                 ASSERT_EQ(vec[i + stack_consumed.dependency], i * 2);
135             break;
136         }
137     } while (true);
138     t.join();
139     delete[] vec;
140 }
141 }