1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef TEST_BENCHMARK_ATOMIC_WAIT_HELPER_H
10#define TEST_BENCHMARK_ATOMIC_WAIT_HELPER_H
11
12#include <atomic>
13#include <chrono>
14#include <exception>
15#include <stop_token>
16#include <thread>
17
18struct HighPrioTask {
19 sched_param param;
20 pthread_attr_t attr_t;
21 pthread_t thread;
22 std::atomic_bool stopped{false};
23
24 HighPrioTask(const HighPrioTask&) = delete;
25
26 HighPrioTask() {
27 pthread_attr_init(attr: &attr_t);
28 pthread_attr_setschedpolicy(attr: &attr_t, SCHED_FIFO);
29 param.sched_priority = sched_get_priority_max(SCHED_FIFO);
30 pthread_attr_setschedparam(attr: &attr_t, param: &param);
31 pthread_attr_setinheritsched(attr: &attr_t, PTHREAD_EXPLICIT_SCHED);
32
33 auto thread_fun = [](void* arg) -> void* {
34 auto* stop = reinterpret_cast<std::atomic_bool*>(arg);
35 while (!stop->load(m: std::memory_order_relaxed)) {
36 // spin
37 }
38 return nullptr;
39 };
40
41 if (pthread_create(newthread: &thread, attr: &attr_t, start_routine: thread_fun, arg: &stopped) != 0) {
42 throw std::runtime_error("failed to create thread");
43 }
44 }
45
46 ~HighPrioTask() {
47 stopped = true;
48 pthread_attr_destroy(attr: &attr_t);
49 pthread_join(th: thread, thread_return: nullptr);
50 }
51};
52
53template <std::size_t N>
54struct NumHighPrioTasks {
55 static constexpr auto value = N;
56};
57
58template <std::size_t N>
59struct NumWaitingThreads {
60 static constexpr auto value = N;
61};
62
63template <std::size_t N>
64struct NumberOfAtomics {
65 static constexpr auto value = N;
66};
67
68struct KeepNotifying {
69 template <class Atomic>
70 static void notify(Atomic& a, std::stop_token st) {
71 while (!st.stop_requested()) {
72 a.fetch_add(1, std::memory_order_relaxed);
73 a.notify_all();
74 }
75 }
76};
77
78template <std::size_t N>
79struct NotifyEveryNus {
80 template <class Atomic>
81 static void notify(Atomic& a, std::stop_token st) {
82 while (!st.stop_requested()) {
83 auto start = std::chrono::system_clock::now();
84 a.fetch_add(1, std::memory_order_relaxed);
85 a.notify_all();
86 while (std::chrono::system_clock::now() - start < std::chrono::microseconds{N}) {
87 }
88 }
89 }
90};
91
92#endif // TEST_BENCHMARK_ATOMIC_WAIT_HELPER_H

source code of libcxx/test/benchmarks/atomic_wait_helper.h