================ @@ -0,0 +1,114 @@ +//===----------------------------------------------------------------------===// +// +// 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_POLICY_H +#define LLDB_TARGET_POLICY_H + +#include "llvm/ADT/SmallVector.h" + +#include <cassert> + +namespace lldb_private { + +/// Describes what view of the process a thread should see and what +/// operations it is allowed to perform. +/// +/// Frame providers are a public illusion layered on top of the private +/// reality (the unwinder stack). The private state thread manages the +/// stop of that private reality, so the correct view for its logic IS the +/// private reality. The public illusion is only applied once the process +/// has settled and clients query the stopped state. +/// +/// This struct is a pure data store -- no business logic. It is pushed +/// onto a per-thread stack (PolicyStack) so that code +/// can consult the current policy instead of comparing host thread +/// identities. +struct Policy { + /// What view of the process this thread sees. + enum class View { + Public, ///< Provider-augmented frames, public state, public run lock. + Private, ///< Parent (unwinder) frames, private state, private run lock. + }; + + /// What operations this thread is allowed to perform. + /// Enforced at specific callsites, not by the policy itself. + struct Capabilities { + bool can_evaluate_expressions = true; + /// Whether expression evaluation may resume all threads to avoid + /// deadlocks (e.g. when a lock is held by another thread). + bool can_run_all_threads = true; + /// Whether the expression runner may fall back to running all threads + /// after a single-thread attempt times out. + bool can_try_all_threads = true; + bool can_run_breakpoint_actions = true; + bool can_load_frame_providers = true; + bool can_run_frame_recognizers = true; + }; + + View view = View::Public; + Capabilities capabilities; + + static Policy PublicState() { return {}; } + + static Policy PrivateState() { + Policy p; + p.view = View::Private; + p.capabilities.can_load_frame_providers = false; + p.capabilities.can_run_frame_recognizers = false; + return p; + } + + static Policy PublicStateRunningExpression() { + Policy p; + p.capabilities.can_run_breakpoint_actions = false; + return p; + } +}; + +/// Per-thread policy stack. +/// +/// The stack lives in thread_local storage. Each thread has its own stack, +/// initialized with a default-constructed base entry that is never popped. +/// RAII guards (Guard) push and pop policies. +/// +/// For thread pool workers that don't inherit thread_local storage, the +/// policy must be passed into the lambda and pushed onto the worker +/// thread's stack when the task starts. +class PolicyStack { +public: + static PolicyStack &GetForCurrentThread() { + static thread_local PolicyStack s_stack; + return s_stack; + } + + Policy Current() const { return m_stack.back(); } + + void Push(Policy policy) { m_stack.push_back(std::move(policy)); } + + void Pop() { + assert(!m_stack.empty() && "can't pop the last policy"); + m_stack.pop_back(); + } + ---------------- medismailben wrote:
I'll do it in a follow up where we actually consult the Policy. https://github.com/llvm/llvm-project/pull/195762 _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
