Home | History | Annotate | Download | only in benchmarks
      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, NULL);
     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, NULL);
     47 
     48   while (state.KeepRunning()) {
     49     pthread_setspecific(key, NULL);
     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   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, NULL);
    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, NULL);
    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 NULL;
    176 }
    177 
    178 static 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 }
    187 BIONIC_BENCHMARK(BM_pthread_create);
    188 
    189 static void* RunThread(void*) {
    190   return NULL;
    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, NULL, RunThread, &state);
    197     pthread_join(thread, NULL);
    198   }
    199 }
    200 BIONIC_BENCHMARK(BM_pthread_create_and_run);
    201 
    202 static void* ExitThread(void*) {
    203   pthread_exit(NULL);
    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, NULL, ExitThread, nullptr);
    210     pthread_join(thread, NULL);
    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, NULL);
    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, NULL);
    232     state.ResumeTiming();
    233 
    234     pthread_key_delete(key);
    235   }
    236 }
    237 BIONIC_BENCHMARK(BM_pthread_key_delete);
    238