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 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 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 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 56 static void DummyPthreadOnceInitFunction() { 57 } 58 59 static 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 } 67 BIONIC_BENCHMARK(BM_pthread_once); 68 69 static 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 } 77 BIONIC_BENCHMARK(BM_pthread_mutex_lock); 78 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 89 static 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 } 97 BIONIC_BENCHMARK(BM_pthread_mutex_lock_RECURSIVE); 98 99 namespace { 100 struct PIMutex { 101 pthread_mutex_t mutex; 102 103 explicit 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 118 static 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 } 126 BIONIC_BENCHMARK(BM_pthread_mutex_lock_PI); 127 128 static 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 } 136 BIONIC_BENCHMARK(BM_pthread_mutex_lock_ERRORCHECK_PI); 137 138 static 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 } 146 BIONIC_BENCHMARK(BM_pthread_mutex_lock_RECURSIVE_PI); 147 148 static void BM_pthread_rwlock_read(benchmark::State& state) { 149 pthread_rwlock_t lock; 150 pthread_rwlock_init(&lock, nullptr); 151 152 while (state.KeepRunning()) { 153 pthread_rwlock_rdlock(&lock); 154 pthread_rwlock_unlock(&lock); 155 } 156 157 pthread_rwlock_destroy(&lock); 158 } 159 BIONIC_BENCHMARK(BM_pthread_rwlock_read); 160 161 static void BM_pthread_rwlock_write(benchmark::State& state) { 162 pthread_rwlock_t lock; 163 pthread_rwlock_init(&lock, nullptr); 164 165 while (state.KeepRunning()) { 166 pthread_rwlock_wrlock(&lock); 167 pthread_rwlock_unlock(&lock); 168 } 169 170 pthread_rwlock_destroy(&lock); 171 } 172 BIONIC_BENCHMARK(BM_pthread_rwlock_write); 173 174 static void* IdleThread(void*) { 175 return nullptr; 176 } 177 178 static void BM_pthread_create(benchmark::State& state) { 179 while (state.KeepRunning()) { 180 pthread_t thread; 181 pthread_create(&thread, nullptr, IdleThread, nullptr); 182 state.PauseTiming(); 183 pthread_join(thread, nullptr); 184 state.ResumeTiming(); 185 } 186 } 187 BIONIC_BENCHMARK(BM_pthread_create); 188 189 static void* RunThread(void*) { 190 return nullptr; 191 } 192 193 static void BM_pthread_create_and_run(benchmark::State& state) { 194 while (state.KeepRunning()) { 195 pthread_t thread; 196 pthread_create(&thread, nullptr, RunThread, &state); 197 pthread_join(thread, nullptr); 198 } 199 } 200 BIONIC_BENCHMARK(BM_pthread_create_and_run); 201 202 static void* ExitThread(void*) { 203 pthread_exit(nullptr); 204 } 205 206 static void BM_pthread_exit_and_join(benchmark::State& state) { 207 while (state.KeepRunning()) { 208 pthread_t thread; 209 pthread_create(&thread, nullptr, ExitThread, nullptr); 210 pthread_join(thread, nullptr); 211 } 212 } 213 BIONIC_BENCHMARK(BM_pthread_exit_and_join); 214 215 static void BM_pthread_key_create(benchmark::State& state) { 216 while (state.KeepRunning()) { 217 pthread_key_t key; 218 pthread_key_create(&key, nullptr); 219 220 state.PauseTiming(); 221 pthread_key_delete(key); 222 state.ResumeTiming(); 223 } 224 } 225 BIONIC_BENCHMARK(BM_pthread_key_create); 226 227 static 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, nullptr); 232 state.ResumeTiming(); 233 234 pthread_key_delete(key); 235 } 236 } 237 BIONIC_BENCHMARK(BM_pthread_key_delete); 238