Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(45)

Side by Side Diff: base/synchronization/rw_lock_unittest.cc

Issue 1988563002: Create a reader-writer lock implementaiton in base. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Simple-stupid implementaiton for NaCl Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/synchronization/rw_lock.h"
6
7 #include <stdlib.h>
8
9 #include "base/compiler_specific.h"
10 #include "base/macros.h"
11 #include "base/threading/platform_thread.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 namespace base {
15
16 // Basic test to make sure that *Acquire()/*Release() don't crash ----------
danakj 2016/05/19 23:01:37 replace the " ----------" with "." and ditto elsew
Anand Mistry (off Chromium) 2016/05/20 04:06:39 Done.
17
18 class BasicRWLockTestThread : public PlatformThread::Delegate {
19 public:
20 explicit BasicRWLockTestThread(RWLock* lock) : lock_(lock), acquired_(0) {}
21
22 void ThreadMain() override {
23 for (int i = 0; i < 10; i++) {
24 lock_->ReadAcquire();
25 acquired_++;
26 lock_->ReadRelease();
27 }
28 for (int i = 0; i < 10; i++) {
29 lock_->WriteAcquire();
30 acquired_++;
31 PlatformThread::Sleep(TimeDelta::FromMilliseconds(rand() % 20));
32 lock_->WriteRelease();
33 }
34 }
35
36 int acquired() const { return acquired_; }
37
38 private:
39 RWLock* lock_;
40 int acquired_;
41
42 DISALLOW_COPY_AND_ASSIGN(BasicRWLockTestThread);
43 };
44
45 TEST(RWLockTest, Basic) {
46 RWLock lock;
47 BasicRWLockTestThread thread(&lock);
48 PlatformThreadHandle handle;
49
50 ASSERT_TRUE(PlatformThread::Create(0, &thread, &handle));
51
52 int acquired = 0;
53 for (int i = 0; i < 5; i++) {
danakj 2016/05/19 23:01:37 I don't really get the point of this test. What is
Anand Mistry (off Chromium) 2016/05/20 04:06:39 It's a basic sanity test to ensure that acquisitio
54 lock.ReadAcquire();
55 acquired++;
56 lock.ReadRelease();
57 }
58 for (int i = 0; i < 10; i++) {
59 lock.WriteAcquire();
60 acquired++;
61 PlatformThread::Sleep(TimeDelta::FromMilliseconds(rand() % 20));
62 lock.WriteRelease();
63 }
64 for (int i = 0; i < 5; i++) {
65 lock.ReadAcquire();
66 acquired++;
67 lock.ReadRelease();
68 }
69
70 PlatformThread::Join(handle);
71
72 EXPECT_EQ(20, acquired);
73 EXPECT_GE(20, thread.acquired());
74 }
75
76 // Tests that reader locks allow multiple simultaneous acquisitions ---------
77
78 class ReaderRWLockTestThread : public PlatformThread::Delegate {
79 public:
80 ReaderRWLockTestThread(RWLock* lock) : lock_(lock) {}
81
82 void ThreadMain() override {
83 lock_->ReadAcquire();
danakj 2016/05/19 23:01:37 Use AutoReadLock
Anand Mistry (off Chromium) 2016/05/20 04:06:39 Done.
84 did_acquire_ = true;
85 lock_->ReadRelease();
86 }
87
88 bool did_acquire() const { return did_acquire_; }
89
90 private:
91 RWLock* lock_;
92 bool did_acquire_ = false;
93
94 DISALLOW_COPY_AND_ASSIGN(ReaderRWLockTestThread);
95 };
96
97 TEST(RWLockTest, ReaderTwoThreads) {
98 RWLock lock;
99
100 AutoReadLock auto_lock(lock);
101
102 ReaderRWLockTestThread thread(&lock);
103 PlatformThreadHandle handle;
104
105 ASSERT_TRUE(PlatformThread::Create(0, &thread, &handle));
106 PlatformThread::Join(handle);
107 EXPECT_TRUE(thread.did_acquire());
108 }
109
110 // Tests that writer locks actually exclude ---------------------------------
111
112 class WriterRWLockTestThread : public PlatformThread::Delegate {
113 public:
114 WriterRWLockTestThread(RWLock* lock, int* value)
115 : lock_(lock), value_(value) {}
116
117 // Static helper which can also be called from the main thread.
118 static void DoStuff(RWLock* lock, int* value) {
119 for (int i = 0; i < 40; i++) {
120 lock->WriteAcquire();
121 int v = *value;
122 PlatformThread::Sleep(TimeDelta::FromMilliseconds(rand() % 10));
123 *value = v + 1;
124 lock->WriteRelease();
125 }
126 }
127
128 void ThreadMain() override { DoStuff(lock_, value_); }
129
130 private:
131 RWLock* lock_;
132 int* value_;
133
134 DISALLOW_COPY_AND_ASSIGN(WriterRWLockTestThread);
135 };
136
137 TEST(RWLockTest, MutexTwoThreads) {
138 RWLock lock;
139 int value = 0;
140
141 WriterRWLockTestThread thread(&lock, &value);
142 PlatformThreadHandle handle;
143
144 ASSERT_TRUE(PlatformThread::Create(0, &thread, &handle));
145
146 WriterRWLockTestThread::DoStuff(&lock, &value);
danakj 2016/05/19 23:01:37 This seems like you could write a bit more obvious
Anand Mistry (off Chromium) 2016/05/20 04:06:38 Done.
147
148 PlatformThread::Join(handle);
149
150 EXPECT_EQ(2 * 40, value);
151 }
152
153 TEST(RWLockTest, MutexFourThreads) {
154 RWLock lock;
155 int value = 0;
156
157 WriterRWLockTestThread thread1(&lock, &value);
158 WriterRWLockTestThread thread2(&lock, &value);
159 WriterRWLockTestThread thread3(&lock, &value);
160 PlatformThreadHandle handle1;
161 PlatformThreadHandle handle2;
162 PlatformThreadHandle handle3;
163
164 ASSERT_TRUE(PlatformThread::Create(0, &thread1, &handle1));
165 ASSERT_TRUE(PlatformThread::Create(0, &thread2, &handle2));
166 ASSERT_TRUE(PlatformThread::Create(0, &thread3, &handle3));
167
168 WriterRWLockTestThread::DoStuff(&lock, &value);
169
170 PlatformThread::Join(handle1);
171 PlatformThread::Join(handle2);
172 PlatformThread::Join(handle3);
173
174 EXPECT_EQ(4 * 40, value);
175 }
176
177 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698