• 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     {
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