blob: 6790c77080cf9bb12df94e7cdfeaf29647de64d7 [file] [log] [blame]
Elliott Hughesb28e4902014-03-11 11:19:06 -07001/*
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
Elliott Hughesb28e4902014-03-11 11:19:06 -070017#include <pthread.h>
18
Elliott Hughes281e06b2016-02-17 10:23:52 -080019#include <benchmark/benchmark.h>
Anders Lewisa7b0f882017-07-24 20:01:13 -070020#include "util.h"
Christopher Ferrisdf4942c2015-02-17 19:58:53 -080021
Elliott Hughesb27a8402014-06-10 20:47:49 -070022// Stop GCC optimizing out our pure function.
23/* Must not be static! */ pthread_t (*pthread_self_fp)() = pthread_self;
24
Elliott Hughes281e06b2016-02-17 10:23:52 -080025static void BM_pthread_self(benchmark::State& state) {
26 while (state.KeepRunning()) {
Elliott Hughesb27a8402014-06-10 20:47:49 -070027 pthread_self_fp();
Elliott Hughesb28e4902014-03-11 11:19:06 -070028 }
Elliott Hughesb28e4902014-03-11 11:19:06 -070029}
Anders Lewisa7b0f882017-07-24 20:01:13 -070030BIONIC_BENCHMARK(BM_pthread_self);
Elliott Hughesb28e4902014-03-11 11:19:06 -070031
Elliott Hughes281e06b2016-02-17 10:23:52 -080032static void BM_pthread_getspecific(benchmark::State& state) {
Elliott Hughesb28e4902014-03-11 11:19:06 -070033 pthread_key_t key;
Yi Kong32bc0fc2018-08-02 17:31:13 -070034 pthread_key_create(&key, nullptr);
Elliott Hughesb28e4902014-03-11 11:19:06 -070035
Elliott Hughes281e06b2016-02-17 10:23:52 -080036 while (state.KeepRunning()) {
Elliott Hughesb28e4902014-03-11 11:19:06 -070037 pthread_getspecific(key);
38 }
39
Elliott Hughesb28e4902014-03-11 11:19:06 -070040 pthread_key_delete(key);
41}
Anders Lewisa7b0f882017-07-24 20:01:13 -070042BIONIC_BENCHMARK(BM_pthread_getspecific);
Elliott Hughesb28e4902014-03-11 11:19:06 -070043
Elliott Hughes281e06b2016-02-17 10:23:52 -080044static void BM_pthread_setspecific(benchmark::State& state) {
Yabin Cui8cf1b302014-12-03 21:36:24 -080045 pthread_key_t key;
Yi Kong32bc0fc2018-08-02 17:31:13 -070046 pthread_key_create(&key, nullptr);
Yabin Cui8cf1b302014-12-03 21:36:24 -080047
Elliott Hughes281e06b2016-02-17 10:23:52 -080048 while (state.KeepRunning()) {
Yi Kong32bc0fc2018-08-02 17:31:13 -070049 pthread_setspecific(key, nullptr);
Yabin Cui8cf1b302014-12-03 21:36:24 -080050 }
51
Yabin Cui8cf1b302014-12-03 21:36:24 -080052 pthread_key_delete(key);
53}
Anders Lewisa7b0f882017-07-24 20:01:13 -070054BIONIC_BENCHMARK(BM_pthread_setspecific);
Yabin Cui8cf1b302014-12-03 21:36:24 -080055
Elliott Hughes68ae6ad2020-07-21 16:11:30 -070056static void NoOpPthreadOnceInitFunction() {}
Elliott Hughesb28e4902014-03-11 11:19:06 -070057
Elliott Hughes281e06b2016-02-17 10:23:52 -080058static void BM_pthread_once(benchmark::State& state) {
George Burgess IV70591002017-06-27 16:23:45 -070059 static pthread_once_t once = PTHREAD_ONCE_INIT;
Elliott Hughes68ae6ad2020-07-21 16:11:30 -070060 pthread_once(&once, NoOpPthreadOnceInitFunction);
Elliott Hughesb28e4902014-03-11 11:19:06 -070061
Elliott Hughes281e06b2016-02-17 10:23:52 -080062 while (state.KeepRunning()) {
Elliott Hughes68ae6ad2020-07-21 16:11:30 -070063 pthread_once(&once, NoOpPthreadOnceInitFunction);
Elliott Hughesb28e4902014-03-11 11:19:06 -070064 }
Elliott Hughesb28e4902014-03-11 11:19:06 -070065}
Anders Lewisa7b0f882017-07-24 20:01:13 -070066BIONIC_BENCHMARK(BM_pthread_once);
Elliott Hughesb28e4902014-03-11 11:19:06 -070067
Elliott Hughes281e06b2016-02-17 10:23:52 -080068static void BM_pthread_mutex_lock(benchmark::State& state) {
Elliott Hughesb28e4902014-03-11 11:19:06 -070069 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
Elliott Hughesb28e4902014-03-11 11:19:06 -070070
Elliott Hughes281e06b2016-02-17 10:23:52 -080071 while (state.KeepRunning()) {
Elliott Hughesb28e4902014-03-11 11:19:06 -070072 pthread_mutex_lock(&mutex);
73 pthread_mutex_unlock(&mutex);
74 }
Elliott Hughesb28e4902014-03-11 11:19:06 -070075}
Anders Lewisa7b0f882017-07-24 20:01:13 -070076BIONIC_BENCHMARK(BM_pthread_mutex_lock);
Elliott Hughesb28e4902014-03-11 11:19:06 -070077
Colin Crossdaa6b822021-12-15 14:26:43 -080078#if !defined(ANDROID_HOST_MUSL)
Elliott Hughes281e06b2016-02-17 10:23:52 -080079static void BM_pthread_mutex_lock_ERRORCHECK(benchmark::State& state) {
Elliott Hughes212e0e32014-12-01 16:43:51 -080080 pthread_mutex_t mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
Elliott Hughesb28e4902014-03-11 11:19:06 -070081
Elliott Hughes281e06b2016-02-17 10:23:52 -080082 while (state.KeepRunning()) {
Elliott Hughesb28e4902014-03-11 11:19:06 -070083 pthread_mutex_lock(&mutex);
84 pthread_mutex_unlock(&mutex);
85 }
Elliott Hughesb28e4902014-03-11 11:19:06 -070086}
Anders Lewisa7b0f882017-07-24 20:01:13 -070087BIONIC_BENCHMARK(BM_pthread_mutex_lock_ERRORCHECK);
Colin Crossdaa6b822021-12-15 14:26:43 -080088#endif
Elliott Hughesb28e4902014-03-11 11:19:06 -070089
Colin Crossdaa6b822021-12-15 14:26:43 -080090#if !defined(ANDROID_HOST_MUSL)
Elliott Hughes281e06b2016-02-17 10:23:52 -080091static void BM_pthread_mutex_lock_RECURSIVE(benchmark::State& state) {
Elliott Hughes212e0e32014-12-01 16:43:51 -080092 pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
Elliott Hughesb28e4902014-03-11 11:19:06 -070093
Elliott Hughes281e06b2016-02-17 10:23:52 -080094 while (state.KeepRunning()) {
Elliott Hughesb28e4902014-03-11 11:19:06 -070095 pthread_mutex_lock(&mutex);
96 pthread_mutex_unlock(&mutex);
97 }
Elliott Hughesb28e4902014-03-11 11:19:06 -070098}
Anders Lewisa7b0f882017-07-24 20:01:13 -070099BIONIC_BENCHMARK(BM_pthread_mutex_lock_RECURSIVE);
Colin Crossdaa6b822021-12-15 14:26:43 -0800100#endif
Calin Juravle837a9622014-09-16 18:01:44 +0100101
Yabin Cui6b9c85b2018-01-23 12:56:18 -0800102namespace {
103struct PIMutex {
104 pthread_mutex_t mutex;
105
Chih-Hung Hsieh770032d2019-01-02 10:59:48 -0800106 explicit PIMutex(int type) {
Yabin Cui6b9c85b2018-01-23 12:56:18 -0800107 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
115 ~PIMutex() {
116 pthread_mutex_destroy(&mutex);
117 }
118};
119}
120
121static 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}
129BIONIC_BENCHMARK(BM_pthread_mutex_lock_PI);
130
131static 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}
139BIONIC_BENCHMARK(BM_pthread_mutex_lock_ERRORCHECK_PI);
140
141static 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}
149BIONIC_BENCHMARK(BM_pthread_mutex_lock_RECURSIVE_PI);
Yabin Cui6b9c85b2018-01-23 12:56:18 -0800150
Elliott Hughes281e06b2016-02-17 10:23:52 -0800151static void BM_pthread_rwlock_read(benchmark::State& state) {
Calin Juravle837a9622014-09-16 18:01:44 +0100152 pthread_rwlock_t lock;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700153 pthread_rwlock_init(&lock, nullptr);
Calin Juravle837a9622014-09-16 18:01:44 +0100154
Elliott Hughes281e06b2016-02-17 10:23:52 -0800155 while (state.KeepRunning()) {
Calin Juravle837a9622014-09-16 18:01:44 +0100156 pthread_rwlock_rdlock(&lock);
157 pthread_rwlock_unlock(&lock);
158 }
159
Calin Juravle837a9622014-09-16 18:01:44 +0100160 pthread_rwlock_destroy(&lock);
161}
Anders Lewisa7b0f882017-07-24 20:01:13 -0700162BIONIC_BENCHMARK(BM_pthread_rwlock_read);
Calin Juravle837a9622014-09-16 18:01:44 +0100163
Elliott Hughes281e06b2016-02-17 10:23:52 -0800164static void BM_pthread_rwlock_write(benchmark::State& state) {
Calin Juravle837a9622014-09-16 18:01:44 +0100165 pthread_rwlock_t lock;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700166 pthread_rwlock_init(&lock, nullptr);
Calin Juravle837a9622014-09-16 18:01:44 +0100167
Elliott Hughes281e06b2016-02-17 10:23:52 -0800168 while (state.KeepRunning()) {
Calin Juravle837a9622014-09-16 18:01:44 +0100169 pthread_rwlock_wrlock(&lock);
170 pthread_rwlock_unlock(&lock);
171 }
172
Calin Juravle837a9622014-09-16 18:01:44 +0100173 pthread_rwlock_destroy(&lock);
174}
Anders Lewisa7b0f882017-07-24 20:01:13 -0700175BIONIC_BENCHMARK(BM_pthread_rwlock_write);
Yabin Cui8cf1b302014-12-03 21:36:24 -0800176
177static void* IdleThread(void*) {
Yi Kong32bc0fc2018-08-02 17:31:13 -0700178 return nullptr;
Yabin Cui8cf1b302014-12-03 21:36:24 -0800179}
180
Elliott Hughes281e06b2016-02-17 10:23:52 -0800181static void BM_pthread_create(benchmark::State& state) {
182 while (state.KeepRunning()) {
183 pthread_t thread;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700184 pthread_create(&thread, nullptr, IdleThread, nullptr);
Elliott Hughes281e06b2016-02-17 10:23:52 -0800185 state.PauseTiming();
Yi Kong32bc0fc2018-08-02 17:31:13 -0700186 pthread_join(thread, nullptr);
Elliott Hughes281e06b2016-02-17 10:23:52 -0800187 state.ResumeTiming();
Yabin Cui8cf1b302014-12-03 21:36:24 -0800188 }
189}
Anders Lewisa7b0f882017-07-24 20:01:13 -0700190BIONIC_BENCHMARK(BM_pthread_create);
Yabin Cui8cf1b302014-12-03 21:36:24 -0800191
Josh Gao286b3a82017-10-24 14:00:09 -0700192static void* RunThread(void*) {
Yi Kong32bc0fc2018-08-02 17:31:13 -0700193 return nullptr;
Yabin Cui8cf1b302014-12-03 21:36:24 -0800194}
195
Elliott Hughes281e06b2016-02-17 10:23:52 -0800196static void BM_pthread_create_and_run(benchmark::State& state) {
197 while (state.KeepRunning()) {
198 pthread_t thread;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700199 pthread_create(&thread, nullptr, RunThread, &state);
200 pthread_join(thread, nullptr);
Yabin Cui8cf1b302014-12-03 21:36:24 -0800201 }
202}
Anders Lewisa7b0f882017-07-24 20:01:13 -0700203BIONIC_BENCHMARK(BM_pthread_create_and_run);
Yabin Cui8cf1b302014-12-03 21:36:24 -0800204
Josh Gao286b3a82017-10-24 14:00:09 -0700205static void* ExitThread(void*) {
Yi Kong32bc0fc2018-08-02 17:31:13 -0700206 pthread_exit(nullptr);
Yabin Cui8cf1b302014-12-03 21:36:24 -0800207}
208
Elliott Hughes281e06b2016-02-17 10:23:52 -0800209static void BM_pthread_exit_and_join(benchmark::State& state) {
210 while (state.KeepRunning()) {
Elliott Hughes281e06b2016-02-17 10:23:52 -0800211 pthread_t thread;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700212 pthread_create(&thread, nullptr, ExitThread, nullptr);
213 pthread_join(thread, nullptr);
Yabin Cui8cf1b302014-12-03 21:36:24 -0800214 }
215}
Anders Lewisa7b0f882017-07-24 20:01:13 -0700216BIONIC_BENCHMARK(BM_pthread_exit_and_join);
Yabin Cui8cf1b302014-12-03 21:36:24 -0800217
Elliott Hughes281e06b2016-02-17 10:23:52 -0800218static void BM_pthread_key_create(benchmark::State& state) {
219 while (state.KeepRunning()) {
220 pthread_key_t key;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700221 pthread_key_create(&key, nullptr);
Elliott Hughes281e06b2016-02-17 10:23:52 -0800222
223 state.PauseTiming();
224 pthread_key_delete(key);
225 state.ResumeTiming();
226 }
227}
Anders Lewisa7b0f882017-07-24 20:01:13 -0700228BIONIC_BENCHMARK(BM_pthread_key_create);
Elliott Hughes281e06b2016-02-17 10:23:52 -0800229
230static void BM_pthread_key_delete(benchmark::State& state) {
231 while (state.KeepRunning()) {
232 state.PauseTiming();
233 pthread_key_t key;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700234 pthread_key_create(&key, nullptr);
Elliott Hughes281e06b2016-02-17 10:23:52 -0800235 state.ResumeTiming();
236
Yabin Cui8cf1b302014-12-03 21:36:24 -0800237 pthread_key_delete(key);
238 }
239}
Anders Lewisa7b0f882017-07-24 20:01:13 -0700240BIONIC_BENCHMARK(BM_pthread_key_delete);