Skip slow lock tests on Windows/debug
[WebKit-https.git] / Tools / TestWebKitAPI / Tests / WTF / Lock.cpp
1 /*
2  * Copyright (C) 2015 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. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include <wtf/Lock.h>
28 #include <wtf/Threading.h>
29 #include <wtf/ThreadingPrimitives.h>
30 #include <wtf/WordLock.h>
31
32 using namespace WTF;
33
34 namespace TestWebKitAPI {
35
36 struct LockInspector {
37     template<typename LockType>
38     static bool isFullyReset(LockType& lock)
39     {
40         return lock.isFullyReset();
41     }
42 };
43
44 template<typename LockType>
45 void runLockTest(unsigned numThreadGroups, unsigned numThreadsPerGroup, unsigned workPerCriticalSection, unsigned numIterations)
46 {
47     std::unique_ptr<LockType[]> locks = std::make_unique<LockType[]>(numThreadGroups);
48     std::unique_ptr<double[]> words = std::make_unique<double[]>(numThreadGroups);
49     std::unique_ptr<ThreadIdentifier[]> threads = std::make_unique<ThreadIdentifier[]>(numThreadGroups * numThreadsPerGroup);
50
51     for (unsigned threadGroupIndex = numThreadGroups; threadGroupIndex--;) {
52         words[threadGroupIndex] = 0;
53
54         for (unsigned threadIndex = numThreadsPerGroup; threadIndex--;) {
55             threads[threadGroupIndex * numThreadsPerGroup + threadIndex] = createThread(
56                 "Lock test thread",
57                 [threadGroupIndex, &locks, &words, numIterations, workPerCriticalSection] () {
58                     for (unsigned i = numIterations; i--;) {
59                         locks[threadGroupIndex].lock();
60                         for (unsigned j = workPerCriticalSection; j--;)
61                             words[threadGroupIndex]++;
62                         locks[threadGroupIndex].unlock();
63                     }
64                 });
65         }
66     }
67
68     for (unsigned threadIndex = numThreadGroups * numThreadsPerGroup; threadIndex--;)
69         waitForThreadCompletion(threads[threadIndex]);
70
71     double expected = 0;
72     for (uint64_t i = static_cast<uint64_t>(numIterations) * workPerCriticalSection * numThreadsPerGroup; i--;)
73         expected++;
74
75     for (unsigned threadGroupIndex = numThreadGroups; threadGroupIndex--;)
76         EXPECT_EQ(expected, words[threadGroupIndex]);
77
78     // Now test that the locks correctly reset themselves. We expect that if a single thread locks
79     // each of the locks twice in a row, then the lock should be in a pristine state.
80     for (unsigned threadGroupIndex = numThreadGroups; threadGroupIndex--;) {
81         for (unsigned i = 2; i--;) {
82             locks[threadGroupIndex].lock();
83             locks[threadGroupIndex].unlock();
84         }
85
86         EXPECT_EQ(true, LockInspector::isFullyReset(locks[threadGroupIndex]));
87     }
88 }
89
90 bool skipSlow()
91 {
92 #if PLATFORM(WIN) && !defined(NDEBUG)
93     return true;
94 #else
95     return false;
96 #endif
97 }
98
99 TEST(WTF_WordLock, UncontendedShortSection)
100 {
101     runLockTest<WordLock>(1, 1, 1, 10000000);
102 }
103
104 TEST(WTF_WordLock, UncontendedLongSection)
105 {
106     runLockTest<WordLock>(1, 1, 10000, 1000);
107 }
108
109 TEST(WTF_WordLock, ContendedShortSection)
110 {
111     if (skipSlow())
112         return;
113     runLockTest<WordLock>(1, 10, 1, 5000000);
114 }
115
116 TEST(WTF_WordLock, ContendedLongSection)
117 {
118     if (skipSlow())
119         return;
120     runLockTest<WordLock>(1, 10, 10000, 10000);
121 }
122
123 TEST(WTF_WordLock, ManyContendedShortSections)
124 {
125     if (skipSlow())
126         return;
127     runLockTest<WordLock>(10, 10, 1, 500000);
128 }
129
130 TEST(WTF_WordLock, ManyContendedLongSections)
131 {
132     if (skipSlow())
133         return;
134     runLockTest<WordLock>(10, 10, 10000, 500);
135 }
136
137 TEST(WTF_Lock, UncontendedShortSection)
138 {
139     runLockTest<Lock>(1, 1, 1, 10000000);
140 }
141
142 TEST(WTF_Lock, UncontendedLongSection)
143 {
144     runLockTest<Lock>(1, 1, 10000, 1000);
145 }
146
147 TEST(WTF_Lock, ContendedShortSection)
148 {
149     if (skipSlow())
150         return;
151     runLockTest<Lock>(1, 10, 1, 10000000);
152 }
153
154 TEST(WTF_Lock, ContendedLongSection)
155 {
156     if (skipSlow())
157         return;
158     runLockTest<Lock>(1, 10, 10000, 10000);
159 }
160
161 TEST(WTF_Lock, ManyContendedShortSections)
162 {
163     if (skipSlow())
164         return;
165     runLockTest<Lock>(10, 10, 1, 500000);
166 }
167
168 TEST(WTF_Lock, ManyContendedLongSections)
169 {
170     if (skipSlow())
171         return;
172     runLockTest<Lock>(10, 10, 10000, 1000);
173 }
174
175 TEST(WTF_Lock, ManyContendedLongerSections)
176 {
177     if (skipSlow())
178         return;
179     runLockTest<Lock>(10, 10, 100000, 1);
180 }
181
182 TEST(WTF_Lock, SectionAddressCollision)
183 {
184     if (skipSlow())
185         return;
186     runLockTest<Lock>(4, 2, 10000, 2000);
187 }
188
189 } // namespace TestWebKitAPI