1 //===-- WatchpointResource.cpp --------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
11 #include "lldb/Breakpoint/WatchpointResource.h"
16 using namespace lldb_private
;
18 WatchpointResource::WatchpointResource(lldb::addr_t addr
, size_t size
,
19 bool read
, bool write
)
20 : m_id(GetNextID()), m_addr(addr
), m_size(size
),
21 m_watch_read(read
), m_watch_write(write
) {}
23 WatchpointResource::~WatchpointResource() {
24 std::lock_guard
<std::mutex
> guard(m_constituents_mutex
);
25 m_constituents
.clear();
28 addr_t
WatchpointResource::GetLoadAddress() const { return m_addr
; }
30 size_t WatchpointResource::GetByteSize() const { return m_size
; }
32 bool WatchpointResource::WatchpointResourceRead() const { return m_watch_read
; }
34 bool WatchpointResource::WatchpointResourceWrite() const {
38 void WatchpointResource::SetType(bool read
, bool write
) {
40 m_watch_write
= write
;
43 wp_resource_id_t
WatchpointResource::GetID() const { return m_id
; }
45 void WatchpointResource::SetID(wp_resource_id_t id
) { m_id
= id
; }
47 bool WatchpointResource::Contains(addr_t addr
) {
48 if (addr
>= m_addr
&& addr
< m_addr
+ m_size
)
53 void WatchpointResource::AddConstituent(const WatchpointSP
&wp_sp
) {
54 std::lock_guard
<std::mutex
> guard(m_constituents_mutex
);
55 m_constituents
.push_back(wp_sp
);
58 void WatchpointResource::RemoveConstituent(WatchpointSP
&wp_sp
) {
59 std::lock_guard
<std::mutex
> guard(m_constituents_mutex
);
61 std::find(m_constituents
.begin(), m_constituents
.end(), wp_sp
);
62 if (it
!= m_constituents
.end())
63 m_constituents
.erase(it
);
66 size_t WatchpointResource::GetNumberOfConstituents() {
67 std::lock_guard
<std::mutex
> guard(m_constituents_mutex
);
68 return m_constituents
.size();
71 bool WatchpointResource::ConstituentsContains(const WatchpointSP
&wp_sp
) {
72 return ConstituentsContains(wp_sp
.get());
75 bool WatchpointResource::ConstituentsContains(const Watchpoint
*wp
) {
76 std::lock_guard
<std::mutex
> guard(m_constituents_mutex
);
77 WatchpointCollection::const_iterator match
=
78 std::find_if(m_constituents
.begin(), m_constituents
.end(),
79 [&wp
](const WatchpointSP
&x
) { return x
.get() == wp
; });
80 return match
!= m_constituents
.end();
83 WatchpointSP
WatchpointResource::GetConstituentAtIndex(size_t idx
) {
84 std::lock_guard
<std::mutex
> guard(m_constituents_mutex
);
85 assert(idx
< m_constituents
.size());
86 if (idx
>= m_constituents
.size())
89 return m_constituents
[idx
];
92 WatchpointResource::WatchpointCollection
93 WatchpointResource::CopyConstituentsList() {
94 std::lock_guard
<std::mutex
> guard(m_constituents_mutex
);
95 return m_constituents
;
98 bool WatchpointResource::ShouldStop(StoppointCallbackContext
*context
) {
99 // LWP_TODO: Need to poll all Watchpoint constituents and see if
100 // we should stop, like BreakpointSites do.
102 m_hit_counter
.Increment();
103 // ShouldStop can do a lot of work, and might even come back and hit
104 // this breakpoint site again. So don't hold the m_constituents_mutex the
105 // whole while. Instead make a local copy of the collection and call
106 // ShouldStop on the copy.
107 WatchpointResourceCollection constituents_copy
;
109 std::lock_guard
<std::recursive_mutex
> guard(m_constituents_mutex
);
110 constituents_copy
= m_constituents
;
112 return constituents_copy
.ShouldStop(context
);
117 void WatchpointResource::Dump(Stream
*s
) const {
121 wp_resource_id_t
WatchpointResource::GetNextID() {
122 static wp_resource_id_t g_next_id
= 0;