1b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes/* 2b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes * Copyright (C) 2014 The Android Open Source Project 3b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes * 4b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 5b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes * you may not use this file except in compliance with the License. 6b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes * You may obtain a copy of the License at 7b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes * 8b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 9b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes * 10b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes * Unless required by applicable law or agreed to in writing, software 11b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 12b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes * See the License for the specific language governing permissions and 14b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes * limitations under the License. 15b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes */ 16b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes 17b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes#include <pthread.h> 18b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes 19a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughes#include <benchmark/benchmark.h> 20df4942c04a63ae6e4f5c78ece9f696d6b8b74d32Christopher Ferris 21b27a840f4b520bfa095db99b0a2e5205634b0003Elliott Hughes// Stop GCC optimizing out our pure function. 22b27a840f4b520bfa095db99b0a2e5205634b0003Elliott Hughes/* Must not be static! */ pthread_t (*pthread_self_fp)() = pthread_self; 23b27a840f4b520bfa095db99b0a2e5205634b0003Elliott Hughes 24a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughesstatic void BM_pthread_self(benchmark::State& state) { 25a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughes while (state.KeepRunning()) { 26b27a840f4b520bfa095db99b0a2e5205634b0003Elliott Hughes pthread_self_fp(); 27b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes } 28b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes} 29a630784fe1124ae5956da2639f1b324c15365fa7Elliott HughesBENCHMARK(BM_pthread_self); 30b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes 31a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughesstatic void BM_pthread_getspecific(benchmark::State& state) { 32b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes pthread_key_t key; 33b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes pthread_key_create(&key, NULL); 34b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes 35a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughes while (state.KeepRunning()) { 36b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes pthread_getspecific(key); 37b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes } 38b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes 39b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes pthread_key_delete(key); 40b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes} 41a630784fe1124ae5956da2639f1b324c15365fa7Elliott HughesBENCHMARK(BM_pthread_getspecific); 42b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes 43a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughesstatic void BM_pthread_setspecific(benchmark::State& state) { 448cf1b305670123aed7638d984ca39bfd22388440Yabin Cui pthread_key_t key; 458cf1b305670123aed7638d984ca39bfd22388440Yabin Cui pthread_key_create(&key, NULL); 468cf1b305670123aed7638d984ca39bfd22388440Yabin Cui 47a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughes while (state.KeepRunning()) { 488cf1b305670123aed7638d984ca39bfd22388440Yabin Cui pthread_setspecific(key, NULL); 498cf1b305670123aed7638d984ca39bfd22388440Yabin Cui } 508cf1b305670123aed7638d984ca39bfd22388440Yabin Cui 518cf1b305670123aed7638d984ca39bfd22388440Yabin Cui pthread_key_delete(key); 528cf1b305670123aed7638d984ca39bfd22388440Yabin Cui} 53a630784fe1124ae5956da2639f1b324c15365fa7Elliott HughesBENCHMARK(BM_pthread_setspecific); 548cf1b305670123aed7638d984ca39bfd22388440Yabin Cui 55b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughesstatic void DummyPthreadOnceInitFunction() { 56b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes} 57b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes 58a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughesstatic void BM_pthread_once(benchmark::State& state) { 59b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes pthread_once_t once = PTHREAD_ONCE_INIT; 60b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes pthread_once(&once, DummyPthreadOnceInitFunction); 61b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes 62a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughes while (state.KeepRunning()) { 63b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes pthread_once(&once, DummyPthreadOnceInitFunction); 64b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes } 65b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes} 66a630784fe1124ae5956da2639f1b324c15365fa7Elliott HughesBENCHMARK(BM_pthread_once); 67b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes 68a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughesstatic void BM_pthread_mutex_lock(benchmark::State& state) { 69b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 70b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes 71a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughes while (state.KeepRunning()) { 72b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes pthread_mutex_lock(&mutex); 73b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes pthread_mutex_unlock(&mutex); 74b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes } 75b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes} 76a630784fe1124ae5956da2639f1b324c15365fa7Elliott HughesBENCHMARK(BM_pthread_mutex_lock); 77b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes 78a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughesstatic void BM_pthread_mutex_lock_ERRORCHECK(benchmark::State& state) { 79212e0e38248860b151b28877225629a988d95b58Elliott Hughes pthread_mutex_t mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; 80b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes 81a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughes while (state.KeepRunning()) { 82b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes pthread_mutex_lock(&mutex); 83b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes pthread_mutex_unlock(&mutex); 84b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes } 85b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes} 86a630784fe1124ae5956da2639f1b324c15365fa7Elliott HughesBENCHMARK(BM_pthread_mutex_lock_ERRORCHECK); 87b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes 88a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughesstatic void BM_pthread_mutex_lock_RECURSIVE(benchmark::State& state) { 89212e0e38248860b151b28877225629a988d95b58Elliott Hughes pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; 90b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes 91a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughes while (state.KeepRunning()) { 92b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes pthread_mutex_lock(&mutex); 93b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes pthread_mutex_unlock(&mutex); 94b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes } 95b28e490b7350b21c5ae9e5b3bb3e082d8357a1b0Elliott Hughes} 96a630784fe1124ae5956da2639f1b324c15365fa7Elliott HughesBENCHMARK(BM_pthread_mutex_lock_RECURSIVE); 97837a962bf5473eeec1668de1104800ff4a53bdd1Calin Juravle 98a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughesstatic void BM_pthread_rwlock_read(benchmark::State& state) { 99837a962bf5473eeec1668de1104800ff4a53bdd1Calin Juravle pthread_rwlock_t lock; 100837a962bf5473eeec1668de1104800ff4a53bdd1Calin Juravle pthread_rwlock_init(&lock, NULL); 101837a962bf5473eeec1668de1104800ff4a53bdd1Calin Juravle 102a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughes while (state.KeepRunning()) { 103837a962bf5473eeec1668de1104800ff4a53bdd1Calin Juravle pthread_rwlock_rdlock(&lock); 104837a962bf5473eeec1668de1104800ff4a53bdd1Calin Juravle pthread_rwlock_unlock(&lock); 105837a962bf5473eeec1668de1104800ff4a53bdd1Calin Juravle } 106837a962bf5473eeec1668de1104800ff4a53bdd1Calin Juravle 107837a962bf5473eeec1668de1104800ff4a53bdd1Calin Juravle pthread_rwlock_destroy(&lock); 108837a962bf5473eeec1668de1104800ff4a53bdd1Calin Juravle} 109a630784fe1124ae5956da2639f1b324c15365fa7Elliott HughesBENCHMARK(BM_pthread_rwlock_read); 110837a962bf5473eeec1668de1104800ff4a53bdd1Calin Juravle 111a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughesstatic void BM_pthread_rwlock_write(benchmark::State& state) { 112837a962bf5473eeec1668de1104800ff4a53bdd1Calin Juravle pthread_rwlock_t lock; 113837a962bf5473eeec1668de1104800ff4a53bdd1Calin Juravle pthread_rwlock_init(&lock, NULL); 114837a962bf5473eeec1668de1104800ff4a53bdd1Calin Juravle 115a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughes while (state.KeepRunning()) { 116837a962bf5473eeec1668de1104800ff4a53bdd1Calin Juravle pthread_rwlock_wrlock(&lock); 117837a962bf5473eeec1668de1104800ff4a53bdd1Calin Juravle pthread_rwlock_unlock(&lock); 118837a962bf5473eeec1668de1104800ff4a53bdd1Calin Juravle } 119837a962bf5473eeec1668de1104800ff4a53bdd1Calin Juravle 120837a962bf5473eeec1668de1104800ff4a53bdd1Calin Juravle pthread_rwlock_destroy(&lock); 121837a962bf5473eeec1668de1104800ff4a53bdd1Calin Juravle} 122a630784fe1124ae5956da2639f1b324c15365fa7Elliott HughesBENCHMARK(BM_pthread_rwlock_write); 1238cf1b305670123aed7638d984ca39bfd22388440Yabin Cui 1248cf1b305670123aed7638d984ca39bfd22388440Yabin Cuistatic void* IdleThread(void*) { 1258cf1b305670123aed7638d984ca39bfd22388440Yabin Cui return NULL; 1268cf1b305670123aed7638d984ca39bfd22388440Yabin Cui} 1278cf1b305670123aed7638d984ca39bfd22388440Yabin Cui 128a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughesstatic void BM_pthread_create(benchmark::State& state) { 129a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughes while (state.KeepRunning()) { 130a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughes pthread_t thread; 1318cf1b305670123aed7638d984ca39bfd22388440Yabin Cui pthread_create(&thread, NULL, IdleThread, NULL); 132a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughes state.PauseTiming(); 1338cf1b305670123aed7638d984ca39bfd22388440Yabin Cui pthread_join(thread, NULL); 134a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughes state.ResumeTiming(); 1358cf1b305670123aed7638d984ca39bfd22388440Yabin Cui } 1368cf1b305670123aed7638d984ca39bfd22388440Yabin Cui} 137a630784fe1124ae5956da2639f1b324c15365fa7Elliott HughesBENCHMARK(BM_pthread_create); 1388cf1b305670123aed7638d984ca39bfd22388440Yabin Cui 139df4942c04a63ae6e4f5c78ece9f696d6b8b74d32Christopher Ferrisstatic void* RunThread(void* arg) { 140a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughes benchmark::State& state = *reinterpret_cast<benchmark::State*>(arg); 141a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughes state.PauseTiming(); 1428cf1b305670123aed7638d984ca39bfd22388440Yabin Cui return NULL; 1438cf1b305670123aed7638d984ca39bfd22388440Yabin Cui} 1448cf1b305670123aed7638d984ca39bfd22388440Yabin Cui 145a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughesstatic void BM_pthread_create_and_run(benchmark::State& state) { 146a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughes while (state.KeepRunning()) { 147a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughes pthread_t thread; 148a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughes pthread_create(&thread, NULL, RunThread, &state); 1498cf1b305670123aed7638d984ca39bfd22388440Yabin Cui pthread_join(thread, NULL); 150a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughes state.ResumeTiming(); 1518cf1b305670123aed7638d984ca39bfd22388440Yabin Cui } 1528cf1b305670123aed7638d984ca39bfd22388440Yabin Cui} 153a630784fe1124ae5956da2639f1b324c15365fa7Elliott HughesBENCHMARK(BM_pthread_create_and_run); 1548cf1b305670123aed7638d984ca39bfd22388440Yabin Cui 155df4942c04a63ae6e4f5c78ece9f696d6b8b74d32Christopher Ferrisstatic void* ExitThread(void* arg) { 156a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughes benchmark::State& state = *reinterpret_cast<benchmark::State*>(arg); 157a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughes state.ResumeTiming(); 1588cf1b305670123aed7638d984ca39bfd22388440Yabin Cui pthread_exit(NULL); 1598cf1b305670123aed7638d984ca39bfd22388440Yabin Cui} 1608cf1b305670123aed7638d984ca39bfd22388440Yabin Cui 161a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughesstatic void BM_pthread_exit_and_join(benchmark::State& state) { 162a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughes while (state.KeepRunning()) { 163a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughes state.PauseTiming(); 164a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughes pthread_t thread; 165a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughes pthread_create(&thread, NULL, ExitThread, &state); 1668cf1b305670123aed7638d984ca39bfd22388440Yabin Cui pthread_join(thread, NULL); 1678cf1b305670123aed7638d984ca39bfd22388440Yabin Cui } 1688cf1b305670123aed7638d984ca39bfd22388440Yabin Cui} 169a630784fe1124ae5956da2639f1b324c15365fa7Elliott HughesBENCHMARK(BM_pthread_exit_and_join); 1708cf1b305670123aed7638d984ca39bfd22388440Yabin Cui 171a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughesstatic void BM_pthread_key_create(benchmark::State& state) { 172a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughes while (state.KeepRunning()) { 173a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughes pthread_key_t key; 1748cf1b305670123aed7638d984ca39bfd22388440Yabin Cui pthread_key_create(&key, NULL); 175a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughes 176a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughes state.PauseTiming(); 1778cf1b305670123aed7638d984ca39bfd22388440Yabin Cui pthread_key_delete(key); 178a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughes state.ResumeTiming(); 1798cf1b305670123aed7638d984ca39bfd22388440Yabin Cui } 1808cf1b305670123aed7638d984ca39bfd22388440Yabin Cui} 181a630784fe1124ae5956da2639f1b324c15365fa7Elliott HughesBENCHMARK(BM_pthread_key_create); 1828cf1b305670123aed7638d984ca39bfd22388440Yabin Cui 183a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughesstatic void BM_pthread_key_delete(benchmark::State& state) { 184a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughes while (state.KeepRunning()) { 185a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughes state.PauseTiming(); 186a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughes pthread_key_t key; 1878cf1b305670123aed7638d984ca39bfd22388440Yabin Cui pthread_key_create(&key, NULL); 188a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughes state.ResumeTiming(); 189a630784fe1124ae5956da2639f1b324c15365fa7Elliott Hughes 1908cf1b305670123aed7638d984ca39bfd22388440Yabin Cui pthread_key_delete(key); 1918cf1b305670123aed7638d984ca39bfd22388440Yabin Cui } 1928cf1b305670123aed7638d984ca39bfd22388440Yabin Cui} 193a630784fe1124ae5956da2639f1b324c15365fa7Elliott HughesBENCHMARK(BM_pthread_key_delete); 194