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