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 25static void BM_pthread_self(benchmark::State& state) { 26 while (state.KeepRunning()) { 27 pthread_self_fp(); 28 } 29} 30BIONIC_BENCHMARK(BM_pthread_self); 31 32static void BM_pthread_getspecific(benchmark::State& state) { 33 pthread_key_t key; 34 pthread_key_create(&key, NULL); 35 36 while (state.KeepRunning()) { 37 pthread_getspecific(key); 38 } 39 40 pthread_key_delete(key); 41} 42BIONIC_BENCHMARK(BM_pthread_getspecific); 43 44static void BM_pthread_setspecific(benchmark::State& state) { 45 pthread_key_t key; 46 pthread_key_create(&key, NULL); 47 48 while (state.KeepRunning()) { 49 pthread_setspecific(key, NULL); 50 } 51 52 pthread_key_delete(key); 53} 54BIONIC_BENCHMARK(BM_pthread_setspecific); 55 56static void DummyPthreadOnceInitFunction() { 57} 58 59static void BM_pthread_once(benchmark::State& state) { 60 static pthread_once_t once = PTHREAD_ONCE_INIT; 61 pthread_once(&once, DummyPthreadOnceInitFunction); 62 63 while (state.KeepRunning()) { 64 pthread_once(&once, DummyPthreadOnceInitFunction); 65 } 66} 67BIONIC_BENCHMARK(BM_pthread_once); 68 69static void BM_pthread_mutex_lock(benchmark::State& state) { 70 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 71 72 while (state.KeepRunning()) { 73 pthread_mutex_lock(&mutex); 74 pthread_mutex_unlock(&mutex); 75 } 76} 77BIONIC_BENCHMARK(BM_pthread_mutex_lock); 78 79static 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} 87BIONIC_BENCHMARK(BM_pthread_mutex_lock_ERRORCHECK); 88 89static void BM_pthread_mutex_lock_RECURSIVE(benchmark::State& state) { 90 pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; 91 92 while (state.KeepRunning()) { 93 pthread_mutex_lock(&mutex); 94 pthread_mutex_unlock(&mutex); 95 } 96} 97BIONIC_BENCHMARK(BM_pthread_mutex_lock_RECURSIVE); 98 99namespace { 100struct PIMutex { 101 pthread_mutex_t mutex; 102 103 PIMutex(int type) { 104 pthread_mutexattr_t attr; 105 pthread_mutexattr_init(&attr); 106 pthread_mutexattr_settype(&attr, type); 107 pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT); 108 pthread_mutex_init(&mutex, &attr); 109 pthread_mutexattr_destroy(&attr); 110 } 111 112 ~PIMutex() { 113 pthread_mutex_destroy(&mutex); 114 } 115}; 116} 117 118static void BM_pthread_mutex_lock_PI(benchmark::State& state) { 119 PIMutex m(PTHREAD_MUTEX_NORMAL); 120 121 while (state.KeepRunning()) { 122 pthread_mutex_lock(&m.mutex); 123 pthread_mutex_unlock(&m.mutex); 124 } 125} 126BIONIC_BENCHMARK(BM_pthread_mutex_lock_PI); 127 128static void BM_pthread_mutex_lock_ERRORCHECK_PI(benchmark::State& state) { 129 PIMutex m(PTHREAD_MUTEX_ERRORCHECK); 130 131 while (state.KeepRunning()) { 132 pthread_mutex_lock(&m.mutex); 133 pthread_mutex_unlock(&m.mutex); 134 } 135} 136BIONIC_BENCHMARK(BM_pthread_mutex_lock_ERRORCHECK_PI); 137 138static void BM_pthread_mutex_lock_RECURSIVE_PI(benchmark::State& state) { 139 PIMutex m(PTHREAD_MUTEX_RECURSIVE); 140 141 while (state.KeepRunning()) { 142 pthread_mutex_lock(&m.mutex); 143 pthread_mutex_unlock(&m.mutex); 144 } 145} 146BIONIC_BENCHMARK(BM_pthread_mutex_lock_RECURSIVE_PI); 147 148static void BM_pthread_rwlock_read(benchmark::State& state) { 149 pthread_rwlock_t lock; 150 pthread_rwlock_init(&lock, NULL); 151 152 while (state.KeepRunning()) { 153 pthread_rwlock_rdlock(&lock); 154 pthread_rwlock_unlock(&lock); 155 } 156 157 pthread_rwlock_destroy(&lock); 158} 159BIONIC_BENCHMARK(BM_pthread_rwlock_read); 160 161static void BM_pthread_rwlock_write(benchmark::State& state) { 162 pthread_rwlock_t lock; 163 pthread_rwlock_init(&lock, NULL); 164 165 while (state.KeepRunning()) { 166 pthread_rwlock_wrlock(&lock); 167 pthread_rwlock_unlock(&lock); 168 } 169 170 pthread_rwlock_destroy(&lock); 171} 172BIONIC_BENCHMARK(BM_pthread_rwlock_write); 173 174static void* IdleThread(void*) { 175 return NULL; 176} 177 178static void BM_pthread_create(benchmark::State& state) { 179 while (state.KeepRunning()) { 180 pthread_t thread; 181 pthread_create(&thread, NULL, IdleThread, NULL); 182 state.PauseTiming(); 183 pthread_join(thread, NULL); 184 state.ResumeTiming(); 185 } 186} 187BIONIC_BENCHMARK(BM_pthread_create); 188 189static void* RunThread(void*) { 190 return NULL; 191} 192 193static void BM_pthread_create_and_run(benchmark::State& state) { 194 while (state.KeepRunning()) { 195 pthread_t thread; 196 pthread_create(&thread, NULL, RunThread, &state); 197 pthread_join(thread, NULL); 198 } 199} 200BIONIC_BENCHMARK(BM_pthread_create_and_run); 201 202static void* ExitThread(void*) { 203 pthread_exit(NULL); 204} 205 206static void BM_pthread_exit_and_join(benchmark::State& state) { 207 while (state.KeepRunning()) { 208 pthread_t thread; 209 pthread_create(&thread, NULL, ExitThread, nullptr); 210 pthread_join(thread, NULL); 211 } 212} 213BIONIC_BENCHMARK(BM_pthread_exit_and_join); 214 215static void BM_pthread_key_create(benchmark::State& state) { 216 while (state.KeepRunning()) { 217 pthread_key_t key; 218 pthread_key_create(&key, NULL); 219 220 state.PauseTiming(); 221 pthread_key_delete(key); 222 state.ResumeTiming(); 223 } 224} 225BIONIC_BENCHMARK(BM_pthread_key_create); 226 227static void BM_pthread_key_delete(benchmark::State& state) { 228 while (state.KeepRunning()) { 229 state.PauseTiming(); 230 pthread_key_t key; 231 pthread_key_create(&key, NULL); 232 state.ResumeTiming(); 233 234 pthread_key_delete(key); 235 } 236} 237BIONIC_BENCHMARK(BM_pthread_key_delete); 238