• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <pthread.h>
18 
19 #include <benchmark/benchmark.h>
20 #include "util.h"
21 
22 // Stop GCC optimizing out our pure function.
23 /* Must not be static! */ pthread_t (*pthread_self_fp)() = pthread_self;
24 
BM_pthread_self(benchmark::State & state)25 static void BM_pthread_self(benchmark::State& state) {
26   while (state.KeepRunning()) {
27     pthread_self_fp();
28   }
29 }
30 BIONIC_BENCHMARK(BM_pthread_self);
31 
BM_pthread_getspecific(benchmark::State & state)32 static void BM_pthread_getspecific(benchmark::State& state) {
33   pthread_key_t key;
34   pthread_key_create(&key, nullptr);
35 
36   while (state.KeepRunning()) {
37     pthread_getspecific(key);
38   }
39 
40   pthread_key_delete(key);
41 }
42 BIONIC_BENCHMARK(BM_pthread_getspecific);
43 
BM_pthread_setspecific(benchmark::State & state)44 static void BM_pthread_setspecific(benchmark::State& state) {
45   pthread_key_t key;
46   pthread_key_create(&key, nullptr);
47 
48   while (state.KeepRunning()) {
49     pthread_setspecific(key, nullptr);
50   }
51 
52   pthread_key_delete(key);
53 }
54 BIONIC_BENCHMARK(BM_pthread_setspecific);
55 
NoOpPthreadOnceInitFunction()56 static void NoOpPthreadOnceInitFunction() {}
57 
BM_pthread_once(benchmark::State & state)58 static void BM_pthread_once(benchmark::State& state) {
59   static pthread_once_t once = PTHREAD_ONCE_INIT;
60   pthread_once(&once, NoOpPthreadOnceInitFunction);
61 
62   while (state.KeepRunning()) {
63     pthread_once(&once, NoOpPthreadOnceInitFunction);
64   }
65 }
66 BIONIC_BENCHMARK(BM_pthread_once);
67 
BM_pthread_mutex_lock(benchmark::State & state)68 static void BM_pthread_mutex_lock(benchmark::State& state) {
69   pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
70 
71   while (state.KeepRunning()) {
72     pthread_mutex_lock(&mutex);
73     pthread_mutex_unlock(&mutex);
74   }
75 }
76 BIONIC_BENCHMARK(BM_pthread_mutex_lock);
77 
78 #if !defined(ANDROID_HOST_MUSL)
BM_pthread_mutex_lock_ERRORCHECK(benchmark::State & state)79 static void BM_pthread_mutex_lock_ERRORCHECK(benchmark::State& state) {
80   pthread_mutex_t mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
81 
82   while (state.KeepRunning()) {
83     pthread_mutex_lock(&mutex);
84     pthread_mutex_unlock(&mutex);
85   }
86 }
87 BIONIC_BENCHMARK(BM_pthread_mutex_lock_ERRORCHECK);
88 #endif
89 
90 #if !defined(ANDROID_HOST_MUSL)
BM_pthread_mutex_lock_RECURSIVE(benchmark::State & state)91 static void BM_pthread_mutex_lock_RECURSIVE(benchmark::State& state) {
92   pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
93 
94   while (state.KeepRunning()) {
95     pthread_mutex_lock(&mutex);
96     pthread_mutex_unlock(&mutex);
97   }
98 }
99 BIONIC_BENCHMARK(BM_pthread_mutex_lock_RECURSIVE);
100 #endif
101 
102 namespace {
103 struct PIMutex {
104   pthread_mutex_t mutex;
105 
PIMutex__anon5e5547460111::PIMutex106   explicit PIMutex(int type) {
107     pthread_mutexattr_t attr;
108     pthread_mutexattr_init(&attr);
109     pthread_mutexattr_settype(&attr, type);
110     pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT);
111     pthread_mutex_init(&mutex, &attr);
112     pthread_mutexattr_destroy(&attr);
113   }
114 
~PIMutex__anon5e5547460111::PIMutex115   ~PIMutex() {
116     pthread_mutex_destroy(&mutex);
117   }
118 };
119 }
120 
BM_pthread_mutex_lock_PI(benchmark::State & state)121 static void BM_pthread_mutex_lock_PI(benchmark::State& state) {
122   PIMutex m(PTHREAD_MUTEX_NORMAL);
123 
124   while (state.KeepRunning()) {
125     pthread_mutex_lock(&m.mutex);
126     pthread_mutex_unlock(&m.mutex);
127   }
128 }
129 BIONIC_BENCHMARK(BM_pthread_mutex_lock_PI);
130 
BM_pthread_mutex_lock_ERRORCHECK_PI(benchmark::State & state)131 static void BM_pthread_mutex_lock_ERRORCHECK_PI(benchmark::State& state) {
132   PIMutex m(PTHREAD_MUTEX_ERRORCHECK);
133 
134   while (state.KeepRunning()) {
135     pthread_mutex_lock(&m.mutex);
136     pthread_mutex_unlock(&m.mutex);
137   }
138 }
139 BIONIC_BENCHMARK(BM_pthread_mutex_lock_ERRORCHECK_PI);
140 
BM_pthread_mutex_lock_RECURSIVE_PI(benchmark::State & state)141 static void BM_pthread_mutex_lock_RECURSIVE_PI(benchmark::State& state) {
142   PIMutex m(PTHREAD_MUTEX_RECURSIVE);
143 
144   while (state.KeepRunning()) {
145     pthread_mutex_lock(&m.mutex);
146     pthread_mutex_unlock(&m.mutex);
147   }
148 }
149 BIONIC_BENCHMARK(BM_pthread_mutex_lock_RECURSIVE_PI);
150 
BM_pthread_rwlock_read(benchmark::State & state)151 static void BM_pthread_rwlock_read(benchmark::State& state) {
152   pthread_rwlock_t lock;
153   pthread_rwlock_init(&lock, nullptr);
154 
155   while (state.KeepRunning()) {
156     pthread_rwlock_rdlock(&lock);
157     pthread_rwlock_unlock(&lock);
158   }
159 
160   pthread_rwlock_destroy(&lock);
161 }
162 BIONIC_BENCHMARK(BM_pthread_rwlock_read);
163 
BM_pthread_rwlock_write(benchmark::State & state)164 static void BM_pthread_rwlock_write(benchmark::State& state) {
165   pthread_rwlock_t lock;
166   pthread_rwlock_init(&lock, nullptr);
167 
168   while (state.KeepRunning()) {
169     pthread_rwlock_wrlock(&lock);
170     pthread_rwlock_unlock(&lock);
171   }
172 
173   pthread_rwlock_destroy(&lock);
174 }
175 BIONIC_BENCHMARK(BM_pthread_rwlock_write);
176 
IdleThread(void *)177 static void* IdleThread(void*) {
178   return nullptr;
179 }
180 
BM_pthread_create(benchmark::State & state)181 static void BM_pthread_create(benchmark::State& state) {
182   while (state.KeepRunning()) {
183     pthread_t thread;
184     pthread_create(&thread, nullptr, IdleThread, nullptr);
185     state.PauseTiming();
186     pthread_join(thread, nullptr);
187     state.ResumeTiming();
188   }
189 }
190 BIONIC_BENCHMARK(BM_pthread_create);
191 
RunThread(void *)192 static void* RunThread(void*) {
193   return nullptr;
194 }
195 
BM_pthread_create_and_run(benchmark::State & state)196 static void BM_pthread_create_and_run(benchmark::State& state) {
197   while (state.KeepRunning()) {
198     pthread_t thread;
199     pthread_create(&thread, nullptr, RunThread, &state);
200     pthread_join(thread, nullptr);
201   }
202 }
203 BIONIC_BENCHMARK(BM_pthread_create_and_run);
204 
ExitThread(void *)205 static void* ExitThread(void*) {
206   pthread_exit(nullptr);
207 }
208 
BM_pthread_exit_and_join(benchmark::State & state)209 static void BM_pthread_exit_and_join(benchmark::State& state) {
210   while (state.KeepRunning()) {
211     pthread_t thread;
212     pthread_create(&thread, nullptr, ExitThread, nullptr);
213     pthread_join(thread, nullptr);
214   }
215 }
216 BIONIC_BENCHMARK(BM_pthread_exit_and_join);
217 
BM_pthread_key_create(benchmark::State & state)218 static void BM_pthread_key_create(benchmark::State& state) {
219   while (state.KeepRunning()) {
220     pthread_key_t key;
221     pthread_key_create(&key, nullptr);
222 
223     state.PauseTiming();
224     pthread_key_delete(key);
225     state.ResumeTiming();
226   }
227 }
228 BIONIC_BENCHMARK(BM_pthread_key_create);
229 
BM_pthread_key_delete(benchmark::State & state)230 static void BM_pthread_key_delete(benchmark::State& state) {
231   while (state.KeepRunning()) {
232     state.PauseTiming();
233     pthread_key_t key;
234     pthread_key_create(&key, nullptr);
235     state.ResumeTiming();
236 
237     pthread_key_delete(key);
238   }
239 }
240 BIONIC_BENCHMARK(BM_pthread_key_delete);
241