92 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef TEST_BENCHMARK_ATOMIC_WAIT_HELPER_H10#define TEST_BENCHMARK_ATOMIC_WAIT_HELPER_H11 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_t);28 pthread_attr_setschedpolicy(&attr_t, SCHED_FIFO);29 param.sched_priority = sched_get_priority_max(SCHED_FIFO);30 pthread_attr_setschedparam(&attr_t, ¶m);31 pthread_attr_setinheritsched(&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(std::memory_order_relaxed)) {36 // spin37 }38 return nullptr;39 };40 41 if (pthread_create(&thread, &attr_t, thread_fun, &stopped) != 0) {42 throw std::runtime_error("failed to create thread");43 }44 }45 46 ~HighPrioTask() {47 stopped = true;48 pthread_attr_destroy(&attr_t);49 pthread_join(thread, 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