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
21 // Stop GCC optimizing out our pure function.
22 /* Must not be static! */ pthread_t (*pthread_self_fp)() = pthread_self;
23
BM_pthread_self(benchmark::State & state)24 static void BM_pthread_self(benchmark::State& state) {
25 while (state.KeepRunning()) {
26 pthread_self_fp();
27 }
28 }
29 BENCHMARK(BM_pthread_self);
30
BM_pthread_getspecific(benchmark::State & state)31 static void BM_pthread_getspecific(benchmark::State& state) {
32 pthread_key_t key;
33 pthread_key_create(&key, NULL);
34
35 while (state.KeepRunning()) {
36 pthread_getspecific(key);
37 }
38
39 pthread_key_delete(key);
40 }
41 BENCHMARK(BM_pthread_getspecific);
42
BM_pthread_setspecific(benchmark::State & state)43 static void BM_pthread_setspecific(benchmark::State& state) {
44 pthread_key_t key;
45 pthread_key_create(&key, NULL);
46
47 while (state.KeepRunning()) {
48 pthread_setspecific(key, NULL);
49 }
50
51 pthread_key_delete(key);
52 }
53 BENCHMARK(BM_pthread_setspecific);
54
DummyPthreadOnceInitFunction()55 static void DummyPthreadOnceInitFunction() {
56 }
57
BM_pthread_once(benchmark::State & state)58 static void BM_pthread_once(benchmark::State& state) {
59 pthread_once_t once = PTHREAD_ONCE_INIT;
60 pthread_once(&once, DummyPthreadOnceInitFunction);
61
62 while (state.KeepRunning()) {
63 pthread_once(&once, DummyPthreadOnceInitFunction);
64 }
65 }
66 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 BENCHMARK(BM_pthread_mutex_lock);
77
BM_pthread_mutex_lock_ERRORCHECK(benchmark::State & state)78 static void BM_pthread_mutex_lock_ERRORCHECK(benchmark::State& state) {
79 pthread_mutex_t mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
80
81 while (state.KeepRunning()) {
82 pthread_mutex_lock(&mutex);
83 pthread_mutex_unlock(&mutex);
84 }
85 }
86 BENCHMARK(BM_pthread_mutex_lock_ERRORCHECK);
87
BM_pthread_mutex_lock_RECURSIVE(benchmark::State & state)88 static void BM_pthread_mutex_lock_RECURSIVE(benchmark::State& state) {
89 pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
90
91 while (state.KeepRunning()) {
92 pthread_mutex_lock(&mutex);
93 pthread_mutex_unlock(&mutex);
94 }
95 }
96 BENCHMARK(BM_pthread_mutex_lock_RECURSIVE);
97
BM_pthread_rwlock_read(benchmark::State & state)98 static void BM_pthread_rwlock_read(benchmark::State& state) {
99 pthread_rwlock_t lock;
100 pthread_rwlock_init(&lock, NULL);
101
102 while (state.KeepRunning()) {
103 pthread_rwlock_rdlock(&lock);
104 pthread_rwlock_unlock(&lock);
105 }
106
107 pthread_rwlock_destroy(&lock);
108 }
109 BENCHMARK(BM_pthread_rwlock_read);
110
BM_pthread_rwlock_write(benchmark::State & state)111 static void BM_pthread_rwlock_write(benchmark::State& state) {
112 pthread_rwlock_t lock;
113 pthread_rwlock_init(&lock, NULL);
114
115 while (state.KeepRunning()) {
116 pthread_rwlock_wrlock(&lock);
117 pthread_rwlock_unlock(&lock);
118 }
119
120 pthread_rwlock_destroy(&lock);
121 }
122 BENCHMARK(BM_pthread_rwlock_write);
123
IdleThread(void *)124 static void* IdleThread(void*) {
125 return NULL;
126 }
127
BM_pthread_create(benchmark::State & state)128 static void BM_pthread_create(benchmark::State& state) {
129 while (state.KeepRunning()) {
130 pthread_t thread;
131 pthread_create(&thread, NULL, IdleThread, NULL);
132 state.PauseTiming();
133 pthread_join(thread, NULL);
134 state.ResumeTiming();
135 }
136 }
137 BENCHMARK(BM_pthread_create);
138
RunThread(void * arg)139 static void* RunThread(void* arg) {
140 benchmark::State& state = *reinterpret_cast<benchmark::State*>(arg);
141 state.PauseTiming();
142 return NULL;
143 }
144
BM_pthread_create_and_run(benchmark::State & state)145 static void BM_pthread_create_and_run(benchmark::State& state) {
146 while (state.KeepRunning()) {
147 pthread_t thread;
148 pthread_create(&thread, NULL, RunThread, &state);
149 pthread_join(thread, NULL);
150 state.ResumeTiming();
151 }
152 }
153 BENCHMARK(BM_pthread_create_and_run);
154
ExitThread(void * arg)155 static void* ExitThread(void* arg) {
156 benchmark::State& state = *reinterpret_cast<benchmark::State*>(arg);
157 state.ResumeTiming();
158 pthread_exit(NULL);
159 }
160
BM_pthread_exit_and_join(benchmark::State & state)161 static void BM_pthread_exit_and_join(benchmark::State& state) {
162 while (state.KeepRunning()) {
163 state.PauseTiming();
164 pthread_t thread;
165 pthread_create(&thread, NULL, ExitThread, &state);
166 pthread_join(thread, NULL);
167 }
168 }
169 BENCHMARK(BM_pthread_exit_and_join);
170
BM_pthread_key_create(benchmark::State & state)171 static void BM_pthread_key_create(benchmark::State& state) {
172 while (state.KeepRunning()) {
173 pthread_key_t key;
174 pthread_key_create(&key, NULL);
175
176 state.PauseTiming();
177 pthread_key_delete(key);
178 state.ResumeTiming();
179 }
180 }
181 BENCHMARK(BM_pthread_key_create);
182
BM_pthread_key_delete(benchmark::State & state)183 static void BM_pthread_key_delete(benchmark::State& state) {
184 while (state.KeepRunning()) {
185 state.PauseTiming();
186 pthread_key_t key;
187 pthread_key_create(&key, NULL);
188 state.ResumeTiming();
189
190 pthread_key_delete(key);
191 }
192 }
193 BENCHMARK(BM_pthread_key_delete);
194