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