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 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 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 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 55 static void DummyPthreadOnceInitFunction() { 56 } 57 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 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 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 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 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 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 124 static void* IdleThread(void*) { 125 return NULL; 126 } 127 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 139 static void* RunThread(void* arg) { 140 benchmark::State& state = *reinterpret_cast<benchmark::State*>(arg); 141 state.PauseTiming(); 142 return NULL; 143 } 144 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 155 static void* ExitThread(void* arg) { 156 benchmark::State& state = *reinterpret_cast<benchmark::State*>(arg); 157 state.ResumeTiming(); 158 pthread_exit(NULL); 159 } 160 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 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 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