Path: blob/main/contrib/llvm-project/libcxx/include/__thread/poll_with_backoff.h
35233 views
// -*- 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//===----------------------------------------------------------------------===//89#ifndef _LIBCPP___THREAD_POLL_WITH_BACKOFF_H10#define _LIBCPP___THREAD_POLL_WITH_BACKOFF_H1112#include <__chrono/duration.h>13#include <__chrono/high_resolution_clock.h>14#include <__config>1516#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)17# pragma GCC system_header18#endif1920_LIBCPP_BEGIN_NAMESPACE_STD2122static _LIBCPP_CONSTEXPR const int __libcpp_polling_count = 64;2324// Polls a thread for a condition given by a predicate, and backs off based on a backoff policy25// before polling again.26//27// - __poll is the "test function" that should return true if polling succeeded, and false if it failed.28//29// - __backoff is the "backoff policy", which is called with the duration since we started polling. It should30// return false in order to resume polling, and true if polling should stop entirely for some reason.31// In general, backoff policies sleep for some time before returning control to the polling loop.32//33// - __max_elapsed is the maximum duration to try polling for. If the maximum duration is exceeded,34// the polling loop will return false to report a timeout.35template <class _Poll, class _Backoff>36_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI bool __libcpp_thread_poll_with_backoff(37_Poll&& __poll, _Backoff&& __backoff, chrono::nanoseconds __max_elapsed = chrono::nanoseconds::zero()) {38auto const __start = chrono::high_resolution_clock::now();39for (int __count = 0;;) {40if (__poll())41return true; // __poll completion means success42if (__count < __libcpp_polling_count) {43__count += 1;44continue;45}46chrono::nanoseconds const __elapsed = chrono::high_resolution_clock::now() - __start;47if (__max_elapsed != chrono::nanoseconds::zero() && __max_elapsed < __elapsed)48return false; // timeout failure49if (__backoff(__elapsed))50return false; // __backoff completion means failure51}52}5354// A trivial backoff policy that always immediately returns the control to55// the polling loop.56//57// This is not very well-behaved since it will cause the polling loop to spin,58// so this should most likely only be used on single-threaded systems where there59// are no other threads to compete with.60struct __spinning_backoff_policy {61_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator()(chrono::nanoseconds const&) const { return false; }62};6364_LIBCPP_END_NAMESPACE_STD6566#endif // _LIBCPP___THREAD_POLL_WITH_BACKOFF_H676869