• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) Huawei Technologies Co., Ltd. 2020-2023. All rights reserved.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "pthread.h"
17 #include "semaphore.h"
18 #include "csignal"
19 #if not defined __APPLE__
20 #include "threads.h"
21 #endif
22 #include "unistd.h"
23 #if not defined __APPLE__
24 #include "sys/tgkill.h"
25 #endif
26 #include "ctime"
27 #include "util.h"
28 
Bm_function_pthread_mutexattr_settype(benchmark::State & state)29 static void Bm_function_pthread_mutexattr_settype(benchmark::State &state)
30 {
31     pthread_mutexattr_t mutexAttr;
32     pthread_mutexattr_init(&mutexAttr);
33     while (state.KeepRunning()) {
34         benchmark::DoNotOptimize(pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_NORMAL));
35     }
36     pthread_mutexattr_destroy(&mutexAttr);
37 }
38 
Bm_function_pthread_mutex_trylock_fast(benchmark::State & state)39 static void Bm_function_pthread_mutex_trylock_fast(benchmark::State &state)
40 {
41     pthread_mutexattr_t mutexAttr;
42     pthread_mutexattr_init(&mutexAttr);
43     pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_NORMAL);
44 
45     pthread_mutex_t mutex;
46     pthread_mutex_init(&mutex, &mutexAttr);
47     pthread_mutexattr_destroy(&mutexAttr);
48     while (state.KeepRunning()) {
49         pthread_mutex_trylock(&mutex);
50         pthread_mutex_unlock(&mutex);
51     }
52 }
53 
Bm_function_pthread_mutex_trylock_errchk(benchmark::State & state)54 static void Bm_function_pthread_mutex_trylock_errchk(benchmark::State &state)
55 {
56     pthread_mutexattr_t mutexAttr;
57     pthread_mutexattr_init(&mutexAttr);
58     pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_ERRORCHECK);
59 
60     pthread_mutex_t mutex;
61     pthread_mutex_init(&mutex, &mutexAttr);
62     pthread_mutexattr_destroy(&mutexAttr);
63     while (state.KeepRunning()) {
64         pthread_mutex_trylock(&mutex);
65         pthread_mutex_unlock(&mutex);
66     }
67 }
68 
Bm_function_pthread_mutex_trylock_rec(benchmark::State & state)69 static void Bm_function_pthread_mutex_trylock_rec(benchmark::State &state)
70 {
71     pthread_mutexattr_t mutexAttr;
72     pthread_mutexattr_init(&mutexAttr);
73     pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_RECURSIVE);
74 
75     pthread_mutex_t mutex;
76     pthread_mutex_init(&mutex, &mutexAttr);
77     pthread_mutexattr_destroy(&mutexAttr);
78     while (state.KeepRunning()) {
79         pthread_mutex_trylock(&mutex);
80         pthread_mutex_unlock(&mutex);
81     }
82 }
83 
Bm_function_pthread_mutex_trylock_pi_fast(benchmark::State & state)84 static void Bm_function_pthread_mutex_trylock_pi_fast(benchmark::State &state)
85 {
86     pthread_mutexattr_t mutexAttr;
87     pthread_mutexattr_init(&mutexAttr);
88     pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_NORMAL);
89     pthread_mutexattr_setprotocol(&mutexAttr, PTHREAD_PRIO_INHERIT);
90     pthread_mutex_t mutex;
91     pthread_mutex_init(&mutex, &mutexAttr);
92     pthread_mutexattr_destroy(&mutexAttr);
93     while (state.KeepRunning()) {
94         pthread_mutex_trylock(&mutex);
95         pthread_mutex_unlock(&mutex);
96     }
97 }
98 
Bm_function_pthread_mutex_trylock_pi_errorcheck(benchmark::State & state)99 static void Bm_function_pthread_mutex_trylock_pi_errorcheck(benchmark::State &state)
100 {
101     pthread_mutexattr_t mutexAttr;
102     pthread_mutexattr_init(&mutexAttr);
103     pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_ERRORCHECK);
104     pthread_mutexattr_setprotocol(&mutexAttr, PTHREAD_PRIO_INHERIT);
105     pthread_mutex_t mutex;
106     pthread_mutex_init(&mutex, &mutexAttr);
107     pthread_mutexattr_destroy(&mutexAttr);
108     while (state.KeepRunning()) {
109         pthread_mutex_trylock(&mutex);
110         pthread_mutex_unlock(&mutex);
111     }
112 }
113 
Bm_function_pthread_mutex_trylock_pi_rec(benchmark::State & state)114 static void Bm_function_pthread_mutex_trylock_pi_rec(benchmark::State &state)
115 {
116     pthread_mutexattr_t mutexAttr;
117     pthread_mutexattr_init(&mutexAttr);
118     pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_RECURSIVE);
119     pthread_mutexattr_setprotocol(&mutexAttr, PTHREAD_PRIO_INHERIT);
120     pthread_mutex_t mutex;
121     pthread_mutex_init(&mutex, &mutexAttr);
122     pthread_mutexattr_destroy(&mutexAttr);
123     while (state.KeepRunning()) {
124         pthread_mutex_trylock(&mutex);
125         pthread_mutex_unlock(&mutex);
126     }
127 }
128 
Bm_function_pthread_mutex_timedlock_fast(benchmark::State & state)129 static void Bm_function_pthread_mutex_timedlock_fast(benchmark::State &state)
130 {
131     struct timespec ts = {.tv_sec = 1, .tv_nsec = 0};
132 
133     pthread_mutexattr_t mutexAttr;
134     pthread_mutexattr_init(&mutexAttr);
135     pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_NORMAL);
136     pthread_mutex_t mutex;
137     pthread_mutex_init(&mutex, &mutexAttr);
138     pthread_mutexattr_destroy(&mutexAttr);
139     while (state.KeepRunning()) {
140         pthread_mutex_timedlock(&mutex, &ts);
141         pthread_mutex_unlock(&mutex);
142     }
143 }
144 
Bm_function_pthread_mutex_timedlock_errchk(benchmark::State & state)145 static void Bm_function_pthread_mutex_timedlock_errchk(benchmark::State &state)
146 {
147     struct timespec ts = {.tv_sec = 1, .tv_nsec = 0};
148 
149     pthread_mutexattr_t mutexAttr;
150     pthread_mutexattr_init(&mutexAttr);
151     pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_ERRORCHECK);
152 
153     pthread_mutex_t mutex;
154     pthread_mutex_init(&mutex, &mutexAttr);
155     pthread_mutexattr_destroy(&mutexAttr);
156     while (state.KeepRunning()) {
157         pthread_mutex_timedlock(&mutex, &ts);
158         pthread_mutex_unlock(&mutex);
159     }
160 }
161 
Bm_function_pthread_mutex_timedlock_rec(benchmark::State & state)162 static void Bm_function_pthread_mutex_timedlock_rec(benchmark::State &state)
163 {
164     struct timespec ts = {.tv_sec = 1, .tv_nsec = 0};
165 
166     pthread_mutexattr_t mutexAttr;
167     pthread_mutexattr_init(&mutexAttr);
168     pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_RECURSIVE);
169 
170     pthread_mutex_t mutex;
171     pthread_mutex_init(&mutex, &mutexAttr);
172     pthread_mutexattr_destroy(&mutexAttr);
173     while (state.KeepRunning()) {
174         pthread_mutex_timedlock(&mutex, &ts);
175         pthread_mutex_unlock(&mutex);
176     }
177 }
178 
Bm_function_pthread_mutex_timedlock_pi_fast(benchmark::State & state)179 static void Bm_function_pthread_mutex_timedlock_pi_fast(benchmark::State &state)
180 {
181     struct timespec ts = {.tv_sec = 1, .tv_nsec = 0};
182 
183     pthread_mutexattr_t mutexAttr;
184     pthread_mutexattr_init(&mutexAttr);
185     pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_NORMAL);
186     pthread_mutexattr_setprotocol(&mutexAttr, PTHREAD_PRIO_INHERIT);
187     pthread_mutex_t mutex;
188     pthread_mutex_init(&mutex, &mutexAttr);
189     pthread_mutexattr_destroy(&mutexAttr);
190     while (state.KeepRunning()) {
191         pthread_mutex_timedlock(&mutex, &ts);
192         pthread_mutex_unlock(&mutex);
193     }
194 }
195 
Bm_function_pthread_mutex_timedlock_pi_errchk(benchmark::State & state)196 static void Bm_function_pthread_mutex_timedlock_pi_errchk(benchmark::State &state)
197 {
198     struct timespec ts = {.tv_sec = 1, .tv_nsec = 0};
199 
200     pthread_mutexattr_t mutexAttr;
201     pthread_mutexattr_init(&mutexAttr);
202     pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_ERRORCHECK);
203     pthread_mutexattr_setprotocol(&mutexAttr, PTHREAD_PRIO_INHERIT);
204     pthread_mutex_t mutex;
205     pthread_mutex_init(&mutex, &mutexAttr);
206     pthread_mutexattr_destroy(&mutexAttr);
207     while (state.KeepRunning()) {
208         pthread_mutex_timedlock(&mutex, &ts);
209         pthread_mutex_unlock(&mutex);
210     }
211 }
212 
Bm_function_pthread_mutex_timedlock_pi_rec(benchmark::State & state)213 static void Bm_function_pthread_mutex_timedlock_pi_rec(benchmark::State &state)
214 {
215     struct timespec ts = {.tv_sec = 1, .tv_nsec = 0};
216 
217     pthread_mutexattr_t mutexAttr;
218     pthread_mutexattr_init(&mutexAttr);
219     pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_RECURSIVE);
220     pthread_mutexattr_setprotocol(&mutexAttr, PTHREAD_PRIO_INHERIT);
221     pthread_mutex_t mutex;
222     pthread_mutex_init(&mutex, &mutexAttr);
223     pthread_mutexattr_destroy(&mutexAttr);
224     while (state.KeepRunning()) {
225         pthread_mutex_timedlock(&mutex, &ts);
226         pthread_mutex_unlock(&mutex);
227     }
228 }
229 
Bm_function_pthread_rwlock_tryrdlock(benchmark::State & state)230 static void Bm_function_pthread_rwlock_tryrdlock(benchmark::State &state)
231 {
232     pthread_rwlock_t rwlock;
233     pthread_rwlock_init(&rwlock, nullptr);
234     while (state.KeepRunning()) {
235         pthread_rwlock_tryrdlock(&rwlock);
236         pthread_rwlock_unlock(&rwlock);
237     }
238     pthread_rwlock_destroy(&rwlock);
239 }
240 
Bm_function_pthread_mutex_init(benchmark::State & state)241 static void Bm_function_pthread_mutex_init(benchmark::State &state)
242 {
243     pthread_mutex_t mutex;
244 
245     for (auto _ : state) {
246         pthread_mutex_init(&mutex, nullptr);
247     }
248     state.SetBytesProcessed(state.iterations());
249 }
250 
Bm_function_pthread_mutex_init_destroy(benchmark::State & state)251 static void Bm_function_pthread_mutex_init_destroy(benchmark::State &state)
252 {
253     pthread_mutex_t mutex;
254 
255     for (auto _ : state) {
256         pthread_mutex_init(&mutex, nullptr);
257         pthread_mutex_destroy(&mutex);
258     }
259 }
260 
Bm_function_pthread_cond_init(benchmark::State & state)261 static void Bm_function_pthread_cond_init(benchmark::State &state)
262 {
263     pthread_cond_t cond;
264 
265     for (auto _ : state) {
266         pthread_cond_init(&cond, nullptr);
267     }
268     state.SetBytesProcessed(state.iterations());
269 }
270 
Bm_function_pthread_cond_init_destroy(benchmark::State & state)271 static void Bm_function_pthread_cond_init_destroy(benchmark::State &state)
272 {
273     pthread_cond_t cond;
274 
275     for (auto _ : state) {
276         pthread_cond_init(&cond, nullptr);
277         pthread_cond_destroy(&cond);
278     }
279     state.SetBytesProcessed(state.iterations());
280 }
281 
Bm_function_pthread_rwlock_init(benchmark::State & state)282 static void Bm_function_pthread_rwlock_init(benchmark::State &state)
283 {
284     pthread_rwlock_t rwlock;
285 
286     for (auto _ : state) {
287         pthread_rwlock_init(&rwlock, nullptr);
288     }
289     state.SetBytesProcessed(state.iterations());
290 }
291 
Bm_function_pthread_rwlock_init_destroy(benchmark::State & state)292 static void Bm_function_pthread_rwlock_init_destroy(benchmark::State &state)
293 {
294     pthread_rwlock_t rwlock;
295 
296     for (auto _ : state) {
297         pthread_rwlock_init(&rwlock, nullptr);
298         pthread_rwlock_destroy(&rwlock);
299     }
300     state.SetBytesProcessed(state.iterations());
301 }
302 
BM_pthread_rwlock_tryread(benchmark::State & state)303 static void BM_pthread_rwlock_tryread(benchmark::State& state)
304 {
305     pthread_rwlock_t lock;
306     pthread_rwlock_init(&lock, nullptr);
307 
308     while (state.KeepRunning()) {
309         pthread_rwlock_tryrdlock(&lock);
310         pthread_rwlock_unlock(&lock);
311     }
312 
313     pthread_rwlock_destroy(&lock);
314     state.SetBytesProcessed(state.iterations());
315 }
316 
BM_pthread_rwlock_trywrite(benchmark::State & state)317 static void BM_pthread_rwlock_trywrite(benchmark::State& state)
318 {
319     pthread_rwlock_t lock;
320     pthread_rwlock_init(&lock, nullptr);
321 
322     while (state.KeepRunning()) {
323         pthread_rwlock_trywrlock(&lock);
324         pthread_rwlock_unlock(&lock);
325     }
326 
327     pthread_rwlock_destroy(&lock);
328     state.SetBytesProcessed(state.iterations());
329 }
330 
Bm_function_tss_get(benchmark::State & state)331 static void Bm_function_tss_get(benchmark::State &state)
332 {
333     tss_t key;
334     tss_create(&key, nullptr);
335 
336     while (state.KeepRunning()) {
337         tss_get(key);
338     }
339 
340     tss_delete(key);
341     state.SetBytesProcessed(state.iterations());
342 }
343 
Bm_function_pthread_rwlock_timedrdlock(benchmark::State & state)344 static void Bm_function_pthread_rwlock_timedrdlock(benchmark::State &state)
345 {
346     struct timespec tout;
347     time(&tout.tv_sec);
348     tout.tv_nsec = 0;
349     tout.tv_sec += 1;
350     pthread_rwlock_t lock;
351     pthread_rwlock_init(&lock, nullptr);
352 
353     while (state.KeepRunning()) {
354         pthread_rwlock_timedrdlock(&lock, &tout);
355         pthread_rwlock_unlock(&lock);
356     }
357 
358     pthread_rwlock_destroy(&lock);
359     state.SetBytesProcessed(state.iterations());
360 }
361 
Bm_function_pthread_rwlock_timedwrlock(benchmark::State & state)362 static void Bm_function_pthread_rwlock_timedwrlock(benchmark::State &state)
363 {
364     struct timespec tout;
365     time(&tout.tv_sec);
366     tout.tv_nsec = 0;
367     tout.tv_sec += 1;
368     pthread_rwlock_t lock;
369     pthread_rwlock_init(&lock, nullptr);
370 
371     while (state.KeepRunning()) {
372         pthread_rwlock_timedwrlock(&lock, &tout);
373         pthread_rwlock_unlock(&lock);
374     }
375 
376     pthread_rwlock_destroy(&lock);
377     state.SetBytesProcessed(state.iterations());
378 }
379 
Bm_function_pthread_cond_timedwait(benchmark::State & state)380 static void Bm_function_pthread_cond_timedwait(benchmark::State &state)
381 {
382     pthread_mutex_t mutex;
383     pthread_cond_t cond;
384     pthread_mutex_init(&mutex, nullptr);
385     pthread_cond_init(&cond, nullptr);
386     struct timespec ts;
387     clock_gettime(CLOCK_REALTIME, &ts);
388     ts.tv_sec += 1;
389     pthread_mutex_lock(&mutex);
390     while (state.KeepRunning()) {
391         pthread_cond_timedwait(&cond, &mutex, &ts);
392     }
393     pthread_mutex_unlock(&mutex);
394     pthread_mutex_destroy(&mutex);
395     pthread_cond_destroy(&cond);
396     state.SetBytesProcessed(state.iterations());
397 }
398 
399 pthread_cond_t g_cond = PTHREAD_COND_INITIALIZER;
400 pthread_mutex_t g_mutex1 = PTHREAD_MUTEX_INITIALIZER;
ThreadTaskOne(void * arg)401 void* ThreadTaskOne(void* arg)
402 {
403     pthread_mutex_lock(&g_mutex1);
404     pthread_cond_wait(&g_cond, &g_mutex1);
405     sleep(1);
406     pthread_mutex_unlock(&g_mutex1);
407     return nullptr;
408 }
409 
ThreadTaskTwo(void * arg)410 void* ThreadTaskTwo(void* arg)
411 {
412     pthread_mutex_lock(&g_mutex1);
413     pthread_cond_wait(&g_cond, &g_mutex1);
414     sleep(1);
415     pthread_mutex_unlock(&g_mutex1);
416     return nullptr;
417 }
418 
BroadcastNotifyMutex(void * arg)419 void* BroadcastNotifyMutex(void* arg)
420 {
421     benchmark::State *statePtr = (benchmark::State *)arg;
422     statePtr->ResumeTiming();
423     benchmark::DoNotOptimize(pthread_cond_broadcast(&g_cond));
424     statePtr->PauseTiming();
425     return nullptr;
426 }
427 
Bm_function_pthread_cond_broadcast(benchmark::State & state)428 static void Bm_function_pthread_cond_broadcast(benchmark::State &state)
429 {
430     while (state.KeepRunning()) {
431         state.PauseTiming();
432         pthread_t threadOne;
433         pthread_t threadTwo;
434         pthread_t threadThree;
435         pthread_create(&threadOne, nullptr, ThreadTaskOne, nullptr);
436         pthread_create(&threadTwo, nullptr, ThreadTaskTwo, nullptr);
437         sleep(3);
438         pthread_create(&threadThree, nullptr, BroadcastNotifyMutex, &state);
439         pthread_join(threadOne, nullptr);
440         pthread_join(threadTwo, nullptr);
441         pthread_join(threadThree, nullptr);
442     }
443     state.SetBytesProcessed(state.iterations());
444 }
445 
Bm_function_Sem_timewait(benchmark::State & state)446 static void Bm_function_Sem_timewait(benchmark::State &state)
447 {
448     sem_t semp;
449     sem_init(&semp, 0, 1);
450     struct timespec spec;
451     spec.tv_sec = 0;
452     spec.tv_nsec = 5;
453     while (state.KeepRunning()) {
454         sem_timedwait(&semp, &spec);
455     }
456     sem_destroy(&semp);
457 }
458 
Bm_function_Sem_post_wait(benchmark::State & state)459 static void Bm_function_Sem_post_wait(benchmark::State &state)
460 {
461     sem_t semp;
462     sem_init(&semp, 0, 0);
463     struct timespec spec;
464     spec.tv_sec = 0;
465     spec.tv_nsec = 5;
466     while (state.KeepRunning()) {
467         sem_post(&semp);
468         sem_wait(&semp);
469     }
470     sem_destroy(&semp);
471 }
472 
Bm_function_pthread_cond_signal(benchmark::State & state)473 static void Bm_function_pthread_cond_signal(benchmark::State &state)
474 {
475     pthread_cond_t cond;
476     pthread_cond_init(&cond, nullptr);
477     while (state.KeepRunning()) {
478         pthread_cond_signal(&cond);
479     }
480     pthread_cond_destroy(&cond);
481     state.SetBytesProcessed(state.iterations());
482 }
483 
Bm_function_pthread_cond_signal_wait(benchmark::State & state)484 static void Bm_function_pthread_cond_signal_wait(benchmark::State &state)
485 {
486     while (state.KeepRunning()) {
487         state.PauseTiming();
488         pthread_t threadOne;
489         pthread_create(&threadOne, nullptr, ThreadTaskOne, nullptr);
490         sleep(1);
491         state.ResumeTiming();
492         pthread_cond_signal(&g_cond);
493         pthread_join(threadOne, nullptr);
494     }
495     state.SetBytesProcessed(state.iterations());
496 }
497 
Bm_function_Sigaddset(benchmark::State & state)498 static void Bm_function_Sigaddset(benchmark::State &state)
499 {
500     sigset_t set;
501     sigemptyset(&set);
502     for (auto _ : state) {
503         benchmark::DoNotOptimize(sigaddset(&set, SIGUSR1));
504     }
505 }
506 
Bm_function_pthread_setcancelstate(benchmark::State & state)507 static void Bm_function_pthread_setcancelstate(benchmark::State &state)
508 {
509     while (state.KeepRunning()) {
510         pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, nullptr);
511         pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, nullptr);
512     }
513     state.SetBytesProcessed(state.iterations());
514 }
515 
GetThreadId(void * arg)516 void *GetThreadId(void *arg)
517 {
518     pthread_t tid = pthread_self();
519     if (tid == 0) {
520         perror("thread create fail");
521     }
522     return nullptr;
523 }
524 
525 // Check that the two threads are equal
Bm_function_pthread_equal(benchmark::State & state)526 static void Bm_function_pthread_equal(benchmark::State &state)
527 {
528     pthread_t thread1;
529     pthread_t thread2;
530     pthread_create(&thread1, nullptr, GetThreadId, nullptr);
531     pthread_create(&thread2, nullptr, GetThreadId, nullptr);
532     pthread_join(thread1, nullptr);
533     pthread_join(thread2, nullptr);
534     while (state.KeepRunning()) {
535         benchmark::DoNotOptimize(pthread_equal(thread1, thread2));
536     }
537     state.SetBytesProcessed(state.iterations());
538 }
539 
540 // Initialize and destroy thread properties
Bm_function_pthread_attr_init_destroy(benchmark::State & state)541 static void Bm_function_pthread_attr_init_destroy(benchmark::State &state)
542 {
543     pthread_attr_t attr;
544     int ret;
545     pthread_t thread1;
546     pthread_t thread2;
547     while (state.KeepRunning()) {
548         ret = pthread_attr_init(&attr);
549         benchmark::DoNotOptimize(ret);
550         state.PauseTiming();
551         pthread_create(&thread1, &attr, GetThreadId, nullptr);
552         pthread_create(&thread2, &attr, GetThreadId, nullptr);
553         pthread_join(thread1, nullptr);
554         pthread_join(thread2, nullptr);
555         state.ResumeTiming();
556         benchmark::DoNotOptimize(pthread_attr_destroy(&attr));
557     }
558     state.SetBytesProcessed(state.iterations());
559 }
560 
Bm_function_pthread_sigmask(benchmark::State & state)561 static void Bm_function_pthread_sigmask(benchmark::State &state)
562 {
563     sigset_t set;
564     sigset_t oset;
565     sigemptyset(&set);
566     sigaddset(&set, SIGQUIT);
567     sigaddset(&set, SIGUSR1);
568 
569     while (state.KeepRunning()) {
570         benchmark::DoNotOptimize(pthread_sigmask(SIG_BLOCK, &set, &oset));
571         benchmark::DoNotOptimize(pthread_sigmask(SIG_SETMASK, &oset, nullptr));
572     }
573     state.SetBytesProcessed(state.iterations());
574 }
575 
576 static pthread_spinlock_t g_spinLock;
Func(void * arg)577 void* Func(void* arg)
578 {
579     benchmark::State *statePtr = (benchmark::State *)arg;
580     statePtr->ResumeTiming();
581     benchmark::DoNotOptimize(pthread_spin_lock(&g_spinLock));
582     pthread_spin_unlock(&g_spinLock);
583     statePtr->PauseTiming();
584     return nullptr;
585 }
586 
587 // Requests a lock spin lock
Bm_function_pthread_spin_lock_and_spin_unlock(benchmark::State & state)588 static void Bm_function_pthread_spin_lock_and_spin_unlock(benchmark::State &state)
589 {
590     pthread_t tid;
591     pthread_spin_init(&g_spinLock, PTHREAD_PROCESS_PRIVATE);
592     while (state.KeepRunning()) {
593         state.PauseTiming();
594         pthread_create(&tid, nullptr, Func, &state);
595         pthread_join(tid, nullptr);
596         state.ResumeTiming();
597     }
598     pthread_spin_destroy(&g_spinLock);
599     state.SetBytesProcessed(state.iterations());
600 }
601 
Bm_function_pthread_mutexattr_init_and_mutexattr_destroy(benchmark::State & state)602 static void Bm_function_pthread_mutexattr_init_and_mutexattr_destroy(benchmark::State &state)
603 {
604     pthread_mutexattr_t mutexAttr;
605     while (state.KeepRunning()) {
606         pthread_mutexattr_init(&mutexAttr);
607         pthread_mutexattr_destroy(&mutexAttr);
608     }
609     state.SetBytesProcessed(state.iterations());
610 }
611 
ThreadFunc(void * arg)612 void* ThreadFunc(void* arg)
613 {
614     return nullptr;
615 }
616 
Bm_function_pthread_detach(benchmark::State & state)617 static void Bm_function_pthread_detach(benchmark::State &state)
618 {
619     while (state.KeepRunning()) {
620         state.PauseTiming();
621         pthread_t tid;
622         pthread_create(&tid, nullptr, ThreadFunc, nullptr);
623         state.ResumeTiming();
624         pthread_detach(tid);
625     }
626     state.SetBytesProcessed(state.iterations());
627 }
628 
ThreadFuncWait(void * arg)629 void* ThreadFuncWait(void* arg)
630 {
631     sleep(1);
632     return nullptr;
633 }
634 
635 // Set a unique name for the thread which is limited to 16 characters in length
636 // including terminating null bytes
637 constexpr int NAME_LEN = 16;
Bm_function_pthread_setname_np(benchmark::State & state)638 static void Bm_function_pthread_setname_np(benchmark::State &state)
639 {
640     pthread_t tid;
641     char threadName[NAME_LEN] = "THREADFOO";
642     if (pthread_create(&tid, nullptr, ThreadFuncWait, nullptr) != 0) {
643         perror("pthread_create pthread_setname_np");
644     }
645 
646     while (state.KeepRunning()) {
647         if (pthread_setname_np(tid, threadName) != 0) {
648             perror("pthread_setname_np proc");
649         }
650     }
651     pthread_join(tid, nullptr);
652 
653     state.SetBytesProcessed(state.iterations());
654 }
655 
Bm_function_pthread_attr_setschedpolicy(benchmark::State & state)656 static void Bm_function_pthread_attr_setschedpolicy(benchmark::State &state)
657 {
658     pthread_attr_t attr;
659     pthread_attr_init(&attr);
660     int setpolicy = 1;
661     while (state.KeepRunning()) {
662         if (pthread_attr_setschedpolicy(&attr, setpolicy) != 0) {
663             perror("pthread_attr_setschedpolicy proc");
664         }
665     }
666     pthread_attr_destroy(&attr);
667 }
668 
669 // Get the scheduling parameter param of the thread attribute ATTR
Bm_function_pthread_attr_getschedparam(benchmark::State & state)670 static void Bm_function_pthread_attr_getschedparam(benchmark::State &state)
671 {
672     pthread_attr_t attr;
673     struct sched_param setparam;
674     struct sched_param getparam;
675     setparam.sched_priority = 1;
676     pthread_attr_init(&attr);
677     if (pthread_attr_setschedparam(&attr, &setparam) != 0) {
678         perror("pthread_attr_setschedparam pthread_attr_getschedparam");
679     }
680     getparam.sched_priority = 0;
681     while (state.KeepRunning()) {
682         if (pthread_attr_getschedparam(&attr, &getparam) != 0) {
683             perror("pthread_attr_getschedparam proc");
684         }
685     }
686     pthread_attr_destroy(&attr);
687 }
688 
Bm_function_pthread_condattr_setclock(benchmark::State & state)689 static void Bm_function_pthread_condattr_setclock(benchmark::State &state)
690 {
691     pthread_condattr_t attr;
692     pthread_condattr_init(&attr);
693     while (state.KeepRunning()) {
694         if (pthread_condattr_setclock(&attr,  CLOCK_MONOTONIC_RAW) != 0) {
695             perror("pthread_condattr_setclock proc");
696         }
697     }
698     pthread_condattr_destroy(&attr);
699     state.SetBytesProcessed(state.iterations());
700 }
701 
Bm_function_Tgkill(benchmark::State & state)702 static void Bm_function_Tgkill(benchmark::State &state)
703 {
704     pid_t pid = getpid();
705     pid_t pgid = getpgid(pid);
706     for (auto _ : state) {
707         if (tgkill(pgid, pid, SIGCONT) == -1) {
708             perror("tgkill proc");
709         }
710     }
711 }
712 
713 // Set the scheduling parameter param of the thread attribute ATTR
Bm_function_pthread_attr_setschedparam(benchmark::State & state)714 static void Bm_function_pthread_attr_setschedparam(benchmark::State &state)
715 {
716     pthread_attr_t attr;
717     struct sched_param setparam;
718     setparam.sched_priority = 1;
719     pthread_attr_init(&attr);
720     while (state.KeepRunning()) {
721         if (pthread_attr_setschedparam(&attr, &setparam) != 0) {
722             perror("pthread_attr_setschedparam pthread_attr_getschedparam");
723         }
724     }
725     pthread_attr_destroy(&attr);
726 }
PthreadCleanup(void * arg)727 void PthreadCleanup(void* arg)
728 {
729     // empty
730 }
731 
CleanupPushAndPop(void * arg)732 void* CleanupPushAndPop(void* arg)
733 {
734     benchmark::State *statePtr = (benchmark::State *)arg;
735     statePtr->ResumeTiming();
736     pthread_cleanup_push(PthreadCleanup, NULL);
737     pthread_cleanup_pop(0);
738     statePtr->PauseTiming();
739     return nullptr;
740 }
741 
Bm_function_pthread_clean_push_and_pop(benchmark::State & state)742 static void Bm_function_pthread_clean_push_and_pop(benchmark::State &state)
743 {
744     pthread_t tid;
745     while (state.KeepRunning()) {
746         state.PauseTiming();
747         pthread_create(&tid, nullptr, CleanupPushAndPop, &state);
748         pthread_join(tid, nullptr);
749         state.ResumeTiming();
750     }
751 }
752 
753 MUSL_BENCHMARK(Bm_function_Sigaddset);
754 MUSL_BENCHMARK(Bm_function_pthread_cond_signal);
755 MUSL_BENCHMARK(Bm_function_pthread_cond_signal_wait);
756 MUSL_BENCHMARK(Bm_function_pthread_mutexattr_settype);
757 MUSL_BENCHMARK(Bm_function_pthread_mutex_trylock_fast);
758 MUSL_BENCHMARK(Bm_function_pthread_mutex_trylock_errchk);
759 MUSL_BENCHMARK(Bm_function_pthread_mutex_trylock_rec);
760 MUSL_BENCHMARK(Bm_function_pthread_mutex_trylock_pi_fast);
761 MUSL_BENCHMARK(Bm_function_pthread_mutex_trylock_pi_errorcheck);
762 MUSL_BENCHMARK(Bm_function_pthread_mutex_trylock_pi_rec);
763 MUSL_BENCHMARK(Bm_function_pthread_mutex_timedlock_fast);
764 MUSL_BENCHMARK(Bm_function_pthread_mutex_timedlock_errchk);
765 MUSL_BENCHMARK(Bm_function_pthread_mutex_timedlock_rec);
766 MUSL_BENCHMARK(Bm_function_pthread_mutex_timedlock_pi_fast);
767 MUSL_BENCHMARK(Bm_function_pthread_mutex_timedlock_pi_errchk);
768 MUSL_BENCHMARK(Bm_function_pthread_mutex_timedlock_pi_rec);
769 MUSL_BENCHMARK(Bm_function_pthread_rwlock_tryrdlock);
770 MUSL_BENCHMARK(Bm_function_pthread_mutex_init);
771 MUSL_BENCHMARK(Bm_function_pthread_mutex_init_destroy);
772 MUSL_BENCHMARK(Bm_function_pthread_cond_init);
773 MUSL_BENCHMARK(Bm_function_pthread_cond_init_destroy);
774 MUSL_BENCHMARK(Bm_function_pthread_rwlock_init);
775 MUSL_BENCHMARK(Bm_function_pthread_rwlock_init_destroy);
776 MUSL_BENCHMARK(BM_pthread_rwlock_tryread);
777 MUSL_BENCHMARK(BM_pthread_rwlock_trywrite);
778 MUSL_BENCHMARK(Bm_function_tss_get);
779 MUSL_BENCHMARK(Bm_function_pthread_rwlock_timedrdlock);
780 MUSL_BENCHMARK(Bm_function_pthread_rwlock_timedwrlock);
781 MUSL_BENCHMARK(Bm_function_pthread_cond_timedwait);
782 MUSL_BENCHMARK(Bm_function_pthread_cond_broadcast);
783 MUSL_BENCHMARK(Bm_function_Sem_timewait);
784 MUSL_BENCHMARK(Bm_function_Sem_post_wait);
785 MUSL_BENCHMARK(Bm_function_pthread_setcancelstate);
786 MUSL_BENCHMARK(Bm_function_pthread_equal);
787 MUSL_BENCHMARK(Bm_function_pthread_attr_init_destroy);
788 MUSL_BENCHMARK(Bm_function_pthread_sigmask);
789 MUSL_BENCHMARK(Bm_function_pthread_spin_lock_and_spin_unlock);
790 MUSL_BENCHMARK(Bm_function_pthread_mutexattr_init_and_mutexattr_destroy);
791 MUSL_BENCHMARK(Bm_function_pthread_detach);
792 MUSL_BENCHMARK(Bm_function_pthread_setname_np);
793 MUSL_BENCHMARK(Bm_function_pthread_attr_setschedpolicy);
794 MUSL_BENCHMARK(Bm_function_pthread_attr_getschedparam);
795 MUSL_BENCHMARK(Bm_function_pthread_condattr_setclock);
796 MUSL_BENCHMARK(Bm_function_Tgkill);
797 MUSL_BENCHMARK(Bm_function_pthread_attr_setschedparam);
798 MUSL_BENCHMARK(Bm_function_pthread_clean_push_and_pop);
799