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 {
479 pthread_cond_signal(&cond);
480 }
481 pthread_cond_destroy(&cond);
482 state.SetBytesProcessed(state.iterations());
483 }
484
Bm_function_pthread_cond_signal_wait(benchmark::State & state)485 static void Bm_function_pthread_cond_signal_wait(benchmark::State &state)
486 {
487 while (state.KeepRunning()) {
488 state.PauseTiming();
489 pthread_t threadOne;
490 pthread_create(&threadOne, nullptr, ThreadTaskOne, nullptr);
491 sleep(1);
492 state.ResumeTiming();
493 pthread_cond_signal(&g_cond);
494 pthread_join(threadOne, nullptr);
495 }
496 state.SetBytesProcessed(state.iterations());
497 }
498
Bm_function_Sigaddset(benchmark::State & state)499 static void Bm_function_Sigaddset(benchmark::State &state)
500 {
501 sigset_t set;
502 sigemptyset(&set);
503 for (auto _ : state) {
504 benchmark::DoNotOptimize(sigaddset(&set, SIGUSR1));
505 }
506 }
507
Bm_function_pthread_setcancelstate(benchmark::State & state)508 static void Bm_function_pthread_setcancelstate(benchmark::State &state)
509 {
510 while (state.KeepRunning()) {
511 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, nullptr);
512 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, nullptr);
513 }
514 state.SetBytesProcessed(state.iterations());
515 }
516
GetThreadId(void * arg)517 void *GetThreadId(void *arg)
518 {
519 pthread_t tid = pthread_self();
520 if (tid == 0) {
521 perror("thread create fail");
522 }
523 return nullptr;
524 }
525
526 // Check that the two threads are equal
Bm_function_pthread_equal(benchmark::State & state)527 static void Bm_function_pthread_equal(benchmark::State &state)
528 {
529 pthread_t thread1;
530 pthread_t thread2;
531 pthread_create(&thread1, nullptr, GetThreadId, nullptr);
532 pthread_create(&thread2, nullptr, GetThreadId, nullptr);
533 pthread_join(thread1, nullptr);
534 pthread_join(thread2, nullptr);
535 while (state.KeepRunning()) {
536 benchmark::DoNotOptimize(pthread_equal(thread1, thread2));
537 }
538 state.SetBytesProcessed(state.iterations());
539 }
540
541 // Initialize and destroy thread properties
Bm_function_pthread_attr_init_destroy(benchmark::State & state)542 static void Bm_function_pthread_attr_init_destroy(benchmark::State &state)
543 {
544 pthread_attr_t attr;
545 int ret;
546 pthread_t thread1;
547 pthread_t thread2;
548 while (state.KeepRunning()) {
549 ret = pthread_attr_init(&attr);
550 benchmark::DoNotOptimize(ret);
551 state.PauseTiming();
552 pthread_create(&thread1, &attr, GetThreadId, nullptr);
553 pthread_create(&thread2, &attr, GetThreadId, nullptr);
554 pthread_join(thread1, nullptr);
555 pthread_join(thread2, nullptr);
556 state.ResumeTiming();
557 benchmark::DoNotOptimize(pthread_attr_destroy(&attr));
558 }
559 state.SetBytesProcessed(state.iterations());
560 }
561
Bm_function_pthread_sigmask(benchmark::State & state)562 static void Bm_function_pthread_sigmask(benchmark::State &state)
563 {
564 sigset_t set;
565 sigset_t oset;
566 sigemptyset(&set);
567 sigaddset(&set, SIGQUIT);
568 sigaddset(&set, SIGUSR1);
569
570 while (state.KeepRunning()) {
571 benchmark::DoNotOptimize(pthread_sigmask(SIG_BLOCK, &set, &oset));
572 benchmark::DoNotOptimize(pthread_sigmask(SIG_SETMASK, &oset, nullptr));
573 }
574 state.SetBytesProcessed(state.iterations());
575 }
576
577 static pthread_spinlock_t g_spinLock;
Func(void * arg)578 void* Func(void* arg)
579 {
580 benchmark::State *statePtr = (benchmark::State *)arg;
581 statePtr->ResumeTiming();
582 benchmark::DoNotOptimize(pthread_spin_lock(&g_spinLock));
583 pthread_spin_unlock(&g_spinLock);
584 statePtr->PauseTiming();
585 return nullptr;
586 }
587
588 // Requests a lock spin lock
Bm_function_pthread_spin_lock_and_spin_unlock(benchmark::State & state)589 static void Bm_function_pthread_spin_lock_and_spin_unlock(benchmark::State &state)
590 {
591 pthread_t tid;
592 pthread_spin_init(&g_spinLock, PTHREAD_PROCESS_PRIVATE);
593 while (state.KeepRunning()) {
594 state.PauseTiming();
595 pthread_create(&tid, nullptr, Func, &state);
596 pthread_join(tid, nullptr);
597 state.ResumeTiming();
598 }
599 pthread_spin_destroy(&g_spinLock);
600 state.SetBytesProcessed(state.iterations());
601 }
602
Bm_function_pthread_mutexattr_init_and_mutexattr_destroy(benchmark::State & state)603 static void Bm_function_pthread_mutexattr_init_and_mutexattr_destroy(benchmark::State &state)
604 {
605 pthread_mutexattr_t mutexAttr;
606 while (state.KeepRunning()) {
607 pthread_mutexattr_init(&mutexAttr);
608 pthread_mutexattr_destroy(&mutexAttr);
609 }
610 state.SetBytesProcessed(state.iterations());
611 }
612
ThreadFunc(void * arg)613 void* ThreadFunc(void* arg)
614 {
615 return nullptr;
616 }
617
Bm_function_pthread_detach(benchmark::State & state)618 static void Bm_function_pthread_detach(benchmark::State &state)
619 {
620 while (state.KeepRunning()) {
621 state.PauseTiming();
622 pthread_t tid;
623 pthread_create(&tid, nullptr, ThreadFunc, nullptr);
624 state.ResumeTiming();
625 pthread_detach(tid);
626 }
627 state.SetBytesProcessed(state.iterations());
628 }
629
ThreadFuncWait(void * arg)630 void* ThreadFuncWait(void* arg)
631 {
632 sleep(1);
633 return nullptr;
634 }
635
636 // Set a unique name for the thread which is limited to 16 characters in length
637 // including terminating null bytes
638 constexpr int NAME_LEN = 16;
Bm_function_pthread_setname_np(benchmark::State & state)639 static void Bm_function_pthread_setname_np(benchmark::State &state)
640 {
641 pthread_t tid;
642 char threadName[NAME_LEN] = "THREADFOO";
643 if (pthread_create(&tid, nullptr, ThreadFuncWait, nullptr) != 0) {
644 perror("pthread_create pthread_setname_np");
645 }
646
647 while (state.KeepRunning()) {
648 if (pthread_setname_np(tid, threadName) != 0) {
649 perror("pthread_setname_np proc");
650 }
651 }
652 pthread_join(tid, nullptr);
653
654 state.SetBytesProcessed(state.iterations());
655 }
656
Bm_function_pthread_attr_setschedpolicy(benchmark::State & state)657 static void Bm_function_pthread_attr_setschedpolicy(benchmark::State &state)
658 {
659 pthread_attr_t attr;
660 pthread_attr_init(&attr);
661 int setpolicy = 1;
662 while (state.KeepRunning()) {
663 if (pthread_attr_setschedpolicy(&attr, setpolicy) != 0) {
664 perror("pthread_attr_setschedpolicy proc");
665 }
666 }
667 pthread_attr_destroy(&attr);
668 }
669
670 // Get the scheduling parameter param of the thread attribute ATTR
Bm_function_pthread_attr_getschedparam(benchmark::State & state)671 static void Bm_function_pthread_attr_getschedparam(benchmark::State &state)
672 {
673 pthread_attr_t attr;
674 struct sched_param setparam;
675 struct sched_param getparam;
676 setparam.sched_priority = 1;
677 pthread_attr_init(&attr);
678 if (pthread_attr_setschedparam(&attr, &setparam) != 0) {
679 perror("pthread_attr_setschedparam pthread_attr_getschedparam");
680 }
681 getparam.sched_priority = 0;
682 while (state.KeepRunning()) {
683 if (pthread_attr_getschedparam(&attr, &getparam) != 0) {
684 perror("pthread_attr_getschedparam proc");
685 }
686 }
687 pthread_attr_destroy(&attr);
688 }
689
Bm_function_pthread_condattr_setclock(benchmark::State & state)690 static void Bm_function_pthread_condattr_setclock(benchmark::State &state)
691 {
692 pthread_condattr_t attr;
693 pthread_condattr_init(&attr);
694 while (state.KeepRunning()) {
695 if (pthread_condattr_setclock(&attr, CLOCK_MONOTONIC_RAW) != 0) {
696 perror("pthread_condattr_setclock proc");
697 }
698 }
699 pthread_condattr_destroy(&attr);
700 state.SetBytesProcessed(state.iterations());
701 }
702
Bm_function_Tgkill(benchmark::State & state)703 static void Bm_function_Tgkill(benchmark::State &state)
704 {
705 pid_t pid = getpid();
706 pid_t pgid = getpgid(pid);
707 for (auto _ : state) {
708 if (tgkill(pgid, pid, SIGCONT) == -1) {
709 perror("tgkill proc");
710 }
711 }
712 }
713
714 // Set the scheduling parameter param of the thread attribute ATTR
Bm_function_pthread_attr_setschedparam(benchmark::State & state)715 static void Bm_function_pthread_attr_setschedparam(benchmark::State &state)
716 {
717 pthread_attr_t attr;
718 struct sched_param setparam;
719 setparam.sched_priority = 1;
720 pthread_attr_init(&attr);
721 while (state.KeepRunning()) {
722 if (pthread_attr_setschedparam(&attr, &setparam) != 0) {
723 perror("pthread_attr_setschedparam pthread_attr_getschedparam");
724 }
725 }
726 pthread_attr_destroy(&attr);
727 }
PthreadCleanup(void * arg)728 void PthreadCleanup(void* arg)
729 {
730 // empty
731 }
732
CleanupPushAndPop(void * arg)733 void* CleanupPushAndPop(void* arg)
734 {
735 benchmark::State *statePtr = (benchmark::State *)arg;
736 statePtr->ResumeTiming();
737 pthread_cleanup_push(PthreadCleanup, NULL);
738 pthread_cleanup_pop(0);
739 statePtr->PauseTiming();
740 return nullptr;
741 }
742
Bm_function_pthread_clean_push_and_pop(benchmark::State & state)743 static void Bm_function_pthread_clean_push_and_pop(benchmark::State &state)
744 {
745 pthread_t tid;
746 while (state.KeepRunning()) {
747 state.PauseTiming();
748 pthread_create(&tid, nullptr, CleanupPushAndPop, &state);
749 pthread_join(tid, nullptr);
750 state.ResumeTiming();
751 }
752 }
753
754 MUSL_BENCHMARK(Bm_function_Sigaddset);
755 MUSL_BENCHMARK(Bm_function_pthread_cond_signal);
756 MUSL_BENCHMARK(Bm_function_pthread_cond_signal_wait);
757 MUSL_BENCHMARK(Bm_function_pthread_mutexattr_settype);
758 MUSL_BENCHMARK(Bm_function_pthread_mutex_trylock_fast);
759 MUSL_BENCHMARK(Bm_function_pthread_mutex_trylock_errchk);
760 MUSL_BENCHMARK(Bm_function_pthread_mutex_trylock_rec);
761 MUSL_BENCHMARK(Bm_function_pthread_mutex_trylock_pi_fast);
762 MUSL_BENCHMARK(Bm_function_pthread_mutex_trylock_pi_errorcheck);
763 MUSL_BENCHMARK(Bm_function_pthread_mutex_trylock_pi_rec);
764 MUSL_BENCHMARK(Bm_function_pthread_mutex_timedlock_fast);
765 MUSL_BENCHMARK(Bm_function_pthread_mutex_timedlock_errchk);
766 MUSL_BENCHMARK(Bm_function_pthread_mutex_timedlock_rec);
767 MUSL_BENCHMARK(Bm_function_pthread_mutex_timedlock_pi_fast);
768 MUSL_BENCHMARK(Bm_function_pthread_mutex_timedlock_pi_errchk);
769 MUSL_BENCHMARK(Bm_function_pthread_mutex_timedlock_pi_rec);
770 MUSL_BENCHMARK(Bm_function_pthread_rwlock_tryrdlock);
771 MUSL_BENCHMARK(Bm_function_pthread_mutex_init);
772 MUSL_BENCHMARK(Bm_function_pthread_mutex_init_destroy);
773 MUSL_BENCHMARK(Bm_function_pthread_cond_init);
774 MUSL_BENCHMARK(Bm_function_pthread_cond_init_destroy);
775 MUSL_BENCHMARK(Bm_function_pthread_rwlock_init);
776 MUSL_BENCHMARK(Bm_function_pthread_rwlock_init_destroy);
777 MUSL_BENCHMARK(BM_pthread_rwlock_tryread);
778 MUSL_BENCHMARK(BM_pthread_rwlock_trywrite);
779 MUSL_BENCHMARK(Bm_function_tss_get);
780 MUSL_BENCHMARK(Bm_function_pthread_rwlock_timedrdlock);
781 MUSL_BENCHMARK(Bm_function_pthread_rwlock_timedwrlock);
782 MUSL_BENCHMARK(Bm_function_pthread_cond_timedwait);
783 MUSL_BENCHMARK(Bm_function_pthread_cond_broadcast);
784 MUSL_BENCHMARK(Bm_function_Sem_timewait);
785 MUSL_BENCHMARK(Bm_function_Sem_post_wait);
786 MUSL_BENCHMARK(Bm_function_pthread_setcancelstate);
787 MUSL_BENCHMARK(Bm_function_pthread_equal);
788 MUSL_BENCHMARK(Bm_function_pthread_attr_init_destroy);
789 MUSL_BENCHMARK(Bm_function_pthread_sigmask);
790 MUSL_BENCHMARK(Bm_function_pthread_spin_lock_and_spin_unlock);
791 MUSL_BENCHMARK(Bm_function_pthread_mutexattr_init_and_mutexattr_destroy);
792 MUSL_BENCHMARK(Bm_function_pthread_detach);
793 MUSL_BENCHMARK(Bm_function_pthread_setname_np);
794 MUSL_BENCHMARK(Bm_function_pthread_attr_setschedpolicy);
795 MUSL_BENCHMARK(Bm_function_pthread_attr_getschedparam);
796 MUSL_BENCHMARK(Bm_function_pthread_condattr_setclock);
797 MUSL_BENCHMARK(Bm_function_Tgkill);
798 MUSL_BENCHMARK(Bm_function_pthread_attr_setschedparam);
799 MUSL_BENCHMARK(Bm_function_pthread_clean_push_and_pop);
800