Files
clang-r547379/include/lldb/Target/ThreadPlanSingleThreadTimeout.h
Ryan Prichard 6024e5c395 Update prebuilt Clang to r547379 (20.0.0).
clang 20.0.0 (based on r547379) from build 12806354.

Bug: http://b/379133546
Test: N/A
Change-Id: I2eb8938af55d809de674be63cb30cf27e801862b

Upstream-Commit: ad834e67b1105d15ef907f6255d4c96e8e733f57
2025-11-26 14:59:46 -05:00

111 lines
4.0 KiB
C++

//===-- ThreadPlanSingleThreadTimeout.h -------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLDB_TARGET_THREADPLANSINGLETHREADTIMEOUT_H
#define LLDB_TARGET_THREADPLANSINGLETHREADTIMEOUT_H
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlan.h"
#include "lldb/Utility/Event.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/State.h"
#include <chrono>
#include <thread>
namespace lldb_private {
class ThreadPlanSingleThreadTimeout;
//
// Thread plan used by single thread execution to issue timeout. This is useful
// to detect potential deadlock in single thread execution. The timeout measures
// the elapsed time from the last internal stop and gets reset by each internal
// stop to ensure we are accurately detecting execution not moving forward.
// This means this thread plan may be created/destroyed multiple times by the
// parent execution plan.
//
// When a timeout happens, the thread plan resolves the potential deadlock by
// issuing a thread specific async interrupt to enter stop state, then execution
// is resumed with all threads running to resolve the potential deadlock
//
class ThreadPlanSingleThreadTimeout : public ThreadPlan {
enum class State {
WaitTimeout, // Waiting for timeout.
AsyncInterrupt, // Async interrupt has been issued.
Done, // Finished resume all threads.
};
public:
// TODO: allow timeout to be set on per thread plan basis.
struct TimeoutInfo {
// Whether there is a ThreadPlanSingleThreadTimeout instance alive.
bool m_isAlive = false;
ThreadPlanSingleThreadTimeout::State m_last_state = State::WaitTimeout;
};
using TimeoutInfoSP =
std::shared_ptr<ThreadPlanSingleThreadTimeout::TimeoutInfo>;
~ThreadPlanSingleThreadTimeout() override;
// If input \param thread is running in single thread mode, push a
// new ThreadPlanSingleThreadTimeout based on timeout setting from fresh new
// state. The reference of \param info is passed in so that when
// ThreadPlanSingleThreadTimeout got popped its last state can be stored
// in it for future resume.
static void PushNewWithTimeout(Thread &thread, TimeoutInfoSP &info);
// Push a new ThreadPlanSingleThreadTimeout by restoring state from
// input \param info and resume execution.
static void ResumeFromPrevState(Thread &thread, TimeoutInfoSP &info);
void GetDescription(Stream *s, lldb::DescriptionLevel level) override;
bool ValidatePlan(Stream *error) override { return true; }
bool WillStop() override;
void DidPop() override;
bool IsLeafPlan() override { return true; }
bool DoPlanExplainsStop(Event *event_ptr) override;
lldb::StateType GetPlanRunState() override;
static void TimeoutThreadFunc(ThreadPlanSingleThreadTimeout *self);
bool MischiefManaged() override;
bool ShouldStop(Event *event_ptr) override;
void SetStopOthers(bool new_value) override;
bool StopOthers() override;
private:
ThreadPlanSingleThreadTimeout(Thread &thread, TimeoutInfoSP &info);
bool IsTimeoutAsyncInterrupt(Event *event_ptr);
bool HandleEvent(Event *event_ptr);
void HandleTimeout();
uint64_t GetRemainingTimeoutMilliSeconds();
static std::string StateToString(State state);
ThreadPlanSingleThreadTimeout(const ThreadPlanSingleThreadTimeout &) = delete;
const ThreadPlanSingleThreadTimeout &
operator=(const ThreadPlanSingleThreadTimeout &) = delete;
TimeoutInfoSP m_info; // Reference to controlling ThreadPlan's TimeoutInfo.
State m_state;
// Lock for m_wakeup_cv and m_exit_flag between thread plan thread and timer
// thread
std::mutex m_mutex;
std::condition_variable m_wakeup_cv;
std::thread m_timer_thread;
std::chrono::steady_clock::time_point m_timeout_start;
};
} // namespace lldb_private
#endif // LLDB_TARGET_THREADPLANSINGLETHREADTIMEOUT_H