Skip to content

Commit 0ffc76a

Browse files
authored
Merge pull request #9508 from swiftlang/cherrypick-parallel-load
[lldb] Create dependent modules in parallel (llvm#114507)
2 parents 4e50caa + af9459b commit 0ffc76a

File tree

3 files changed

+164
-86
lines changed

3 files changed

+164
-86
lines changed

lldb/include/lldb/Target/PathMappingList.h

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ class PathMappingList {
2525
typedef void (*ChangedCallback)(const PathMappingList &path_list,
2626
void *baton);
2727

28-
// Constructors and Destructors
2928
PathMappingList();
3029

3130
PathMappingList(ChangedCallback callback, void *callback_baton);
@@ -53,12 +52,12 @@ class PathMappingList {
5352
llvm::json::Value ToJSON();
5453

5554
bool IsEmpty() const {
56-
std::lock_guard<std::recursive_mutex> lock(m_mutex);
55+
std::lock_guard<std::mutex> lock(m_pairs_mutex);
5756
return m_pairs.empty();
5857
}
5958

6059
size_t GetSize() const {
61-
std::lock_guard<std::recursive_mutex> lock(m_mutex);
60+
std::lock_guard<std::mutex> lock(m_pairs_mutex);
6261
return m_pairs.size();
6362
}
6463

@@ -134,28 +133,35 @@ class PathMappingList {
134133
/// The newly remapped filespec that is guaranteed to exist.
135134
std::optional<FileSpec> FindFile(const FileSpec &orig_spec) const;
136135

137-
uint32_t FindIndexForPath(llvm::StringRef path) const;
138-
139136
uint32_t GetModificationID() const {
140-
std::lock_guard<std::recursive_mutex> lock(m_mutex);
137+
std::lock_guard<std::mutex> lock(m_pairs_mutex);
141138
return m_mod_id;
142139
}
143140

144141
protected:
145-
mutable std::recursive_mutex m_mutex;
146142
typedef std::pair<ConstString, ConstString> pair;
147143
typedef std::vector<pair> collection;
148144
typedef collection::iterator iterator;
149145
typedef collection::const_iterator const_iterator;
150146

147+
void AppendNoLock(llvm::StringRef path, llvm::StringRef replacement);
148+
uint32_t FindIndexForPathNoLock(llvm::StringRef path) const;
149+
void Notify(bool notify) const;
150+
151151
iterator FindIteratorForPath(ConstString path);
152152

153153
const_iterator FindIteratorForPath(ConstString path) const;
154154

155155
collection m_pairs;
156+
mutable std::mutex m_pairs_mutex;
157+
156158
ChangedCallback m_callback = nullptr;
157159
void *m_callback_baton = nullptr;
158-
uint32_t m_mod_id = 0; // Incremented anytime anything is added or removed.
160+
mutable std::mutex m_callback_mutex;
161+
162+
/// Incremented anytime anything is added to or removed from m_pairs. Also
163+
/// protected by m_pairs_mutex.
164+
uint32_t m_mod_id = 0;
159165
};
160166

161167
} // namespace lldb_private

lldb/source/Target/PathMappingList.cpp

Lines changed: 101 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ PathMappingList::PathMappingList(const PathMappingList &rhs)
4848

4949
const PathMappingList &PathMappingList::operator=(const PathMappingList &rhs) {
5050
if (this != &rhs) {
51-
std::scoped_lock<std::recursive_mutex, std::recursive_mutex> locks(m_mutex, rhs.m_mutex);
51+
std::scoped_lock<std::mutex, std::mutex, std::mutex> locks(
52+
m_callback_mutex, m_pairs_mutex, rhs.m_pairs_mutex);
5253
m_pairs = rhs.m_pairs;
5354
m_callback = nullptr;
5455
m_callback_baton = nullptr;
@@ -59,85 +60,111 @@ const PathMappingList &PathMappingList::operator=(const PathMappingList &rhs) {
5960

6061
PathMappingList::~PathMappingList() = default;
6162

62-
void PathMappingList::Append(llvm::StringRef path, llvm::StringRef replacement,
63-
bool notify) {
64-
std::lock_guard<std::recursive_mutex> lock(m_mutex);
63+
void PathMappingList::AppendNoLock(llvm::StringRef path,
64+
llvm::StringRef replacement) {
6565
++m_mod_id;
6666
m_pairs.emplace_back(pair(NormalizePath(path), NormalizePath(replacement)));
67-
if (notify && m_callback)
68-
m_callback(*this, m_callback_baton);
67+
}
68+
69+
void PathMappingList::Notify(bool notify) const {
70+
ChangedCallback callback = nullptr;
71+
void *baton = nullptr;
72+
{
73+
std::lock_guard<std::mutex> lock(m_callback_mutex);
74+
callback = m_callback;
75+
baton = m_callback_baton;
76+
}
77+
if (notify && callback)
78+
callback(*this, baton);
79+
}
80+
81+
void PathMappingList::Append(llvm::StringRef path, llvm::StringRef replacement,
82+
bool notify) {
83+
{
84+
std::lock_guard<std::mutex> lock(m_pairs_mutex);
85+
AppendNoLock(path, replacement);
86+
}
87+
Notify(notify);
6988
}
7089

7190
void PathMappingList::Append(const PathMappingList &rhs, bool notify) {
72-
std::scoped_lock<std::recursive_mutex, std::recursive_mutex> locks(m_mutex, rhs.m_mutex);
73-
++m_mod_id;
74-
if (!rhs.m_pairs.empty()) {
91+
{
92+
std::scoped_lock<std::mutex, std::mutex> locks(m_pairs_mutex,
93+
rhs.m_pairs_mutex);
94+
++m_mod_id;
95+
if (rhs.m_pairs.empty())
96+
return;
7597
const_iterator pos, end = rhs.m_pairs.end();
7698
for (pos = rhs.m_pairs.begin(); pos != end; ++pos)
7799
m_pairs.push_back(*pos);
78-
if (notify && m_callback)
79-
m_callback(*this, m_callback_baton);
80100
}
101+
Notify(notify);
81102
}
82103

83104
bool PathMappingList::AppendUnique(llvm::StringRef path,
84105
llvm::StringRef replacement, bool notify) {
85106
auto normalized_path = NormalizePath(path);
86107
auto normalized_replacement = NormalizePath(replacement);
87-
std::lock_guard<std::recursive_mutex> lock(m_mutex);
88-
for (const auto &pair : m_pairs) {
89-
if (pair.first.GetStringRef() == normalized_path &&
90-
pair.second.GetStringRef() == normalized_replacement)
91-
return false;
108+
{
109+
std::lock_guard<std::mutex> lock(m_pairs_mutex);
110+
for (const auto &pair : m_pairs) {
111+
if (pair.first.GetStringRef() == normalized_path &&
112+
pair.second.GetStringRef() == normalized_replacement)
113+
return false;
114+
}
115+
AppendNoLock(path, replacement);
92116
}
93-
Append(path, replacement, notify);
117+
Notify(notify);
94118
return true;
95119
}
96120

97121
void PathMappingList::Insert(llvm::StringRef path, llvm::StringRef replacement,
98122
uint32_t index, bool notify) {
99-
std::lock_guard<std::recursive_mutex> lock(m_mutex);
100-
++m_mod_id;
101-
iterator insert_iter;
102-
if (index >= m_pairs.size())
103-
insert_iter = m_pairs.end();
104-
else
105-
insert_iter = m_pairs.begin() + index;
106-
m_pairs.emplace(insert_iter, pair(NormalizePath(path),
107-
NormalizePath(replacement)));
108-
if (notify && m_callback)
109-
m_callback(*this, m_callback_baton);
123+
{
124+
std::lock_guard<std::mutex> lock(m_pairs_mutex);
125+
++m_mod_id;
126+
iterator insert_iter;
127+
if (index >= m_pairs.size())
128+
insert_iter = m_pairs.end();
129+
else
130+
insert_iter = m_pairs.begin() + index;
131+
m_pairs.emplace(insert_iter,
132+
pair(NormalizePath(path), NormalizePath(replacement)));
133+
}
134+
Notify(notify);
110135
}
111136

112137
bool PathMappingList::Replace(llvm::StringRef path, llvm::StringRef replacement,
113138
uint32_t index, bool notify) {
114-
std::lock_guard<std::recursive_mutex> lock(m_mutex);
115-
if (index >= m_pairs.size())
116-
return false;
117-
++m_mod_id;
118-
m_pairs[index] = pair(NormalizePath(path), NormalizePath(replacement));
119-
if (notify && m_callback)
120-
m_callback(*this, m_callback_baton);
139+
{
140+
std::lock_guard<std::mutex> lock(m_pairs_mutex);
141+
if (index >= m_pairs.size())
142+
return false;
143+
++m_mod_id;
144+
m_pairs[index] = pair(NormalizePath(path), NormalizePath(replacement));
145+
}
146+
Notify(notify);
121147
return true;
122148
}
123149

124150
bool PathMappingList::Remove(size_t index, bool notify) {
125-
std::lock_guard<std::recursive_mutex> lock(m_mutex);
126-
if (index >= m_pairs.size())
127-
return false;
151+
{
152+
std::lock_guard<std::mutex> lock(m_pairs_mutex);
153+
if (index >= m_pairs.size())
154+
return false;
128155

129-
++m_mod_id;
130-
iterator iter = m_pairs.begin() + index;
131-
m_pairs.erase(iter);
132-
if (notify && m_callback)
133-
m_callback(*this, m_callback_baton);
156+
++m_mod_id;
157+
iterator iter = m_pairs.begin() + index;
158+
m_pairs.erase(iter);
159+
}
160+
Notify(notify);
134161
return true;
135162
}
136163

137164
// For clients which do not need the pair index dumped, pass a pair_index >= 0
138165
// to only dump the indicated pair.
139166
void PathMappingList::Dump(Stream *s, int pair_index) {
140-
std::lock_guard<std::recursive_mutex> lock(m_mutex);
167+
std::lock_guard<std::mutex> lock(m_pairs_mutex);
141168
unsigned int numPairs = m_pairs.size();
142169

143170
if (pair_index < 0) {
@@ -155,7 +182,7 @@ void PathMappingList::Dump(Stream *s, int pair_index) {
155182

156183
llvm::json::Value PathMappingList::ToJSON() {
157184
llvm::json::Array entries;
158-
std::lock_guard<std::recursive_mutex> lock(m_mutex);
185+
std::lock_guard<std::mutex> lock(m_pairs_mutex);
159186
for (const auto &pair : m_pairs) {
160187
llvm::json::Array entry{pair.first.GetStringRef().str(),
161188
pair.second.GetStringRef().str()};
@@ -165,12 +192,13 @@ llvm::json::Value PathMappingList::ToJSON() {
165192
}
166193

167194
void PathMappingList::Clear(bool notify) {
168-
std::lock_guard<std::recursive_mutex> lock(m_mutex);
169-
if (!m_pairs.empty())
170-
++m_mod_id;
171-
m_pairs.clear();
172-
if (notify && m_callback)
173-
m_callback(*this, m_callback_baton);
195+
{
196+
std::lock_guard<std::mutex> lock(m_pairs_mutex);
197+
if (!m_pairs.empty())
198+
++m_mod_id;
199+
m_pairs.clear();
200+
}
201+
Notify(notify);
174202
}
175203

176204
bool PathMappingList::RemapPath(ConstString path,
@@ -196,7 +224,7 @@ static void AppendPathComponents(FileSpec &path, llvm::StringRef components,
196224

197225
std::optional<FileSpec> PathMappingList::RemapPath(llvm::StringRef mapping_path,
198226
bool only_if_exists) const {
199-
std::lock_guard<std::recursive_mutex> lock(m_mutex);
227+
std::lock_guard<std::mutex> lock(m_pairs_mutex);
200228
if (m_pairs.empty() || mapping_path.empty())
201229
return {};
202230
LazyBool path_is_relative = eLazyBoolCalculate;
@@ -235,7 +263,7 @@ std::optional<llvm::StringRef>
235263
PathMappingList::ReverseRemapPath(const FileSpec &file, FileSpec &fixed) const {
236264
std::string path = file.GetPath();
237265
llvm::StringRef path_ref(path);
238-
std::lock_guard<std::recursive_mutex> lock(m_mutex);
266+
std::lock_guard<std::mutex> lock(m_pairs_mutex);
239267
for (const auto &it : m_pairs) {
240268
llvm::StringRef removed_prefix = it.second.GetStringRef();
241269
if (!path_ref.consume_front(it.second.GetStringRef()))
@@ -264,34 +292,35 @@ PathMappingList::FindFile(const FileSpec &orig_spec) const {
264292

265293
bool PathMappingList::Replace(llvm::StringRef path, llvm::StringRef new_path,
266294
bool notify) {
267-
std::lock_guard<std::recursive_mutex> lock(m_mutex);
268-
uint32_t idx = FindIndexForPath(path);
269-
if (idx < m_pairs.size()) {
295+
{
296+
std::lock_guard<std::mutex> lock(m_pairs_mutex);
297+
uint32_t idx = FindIndexForPathNoLock(path);
298+
if (idx >= m_pairs.size())
299+
return false;
270300
++m_mod_id;
271301
m_pairs[idx].second = ConstString(new_path);
272-
if (notify && m_callback)
273-
m_callback(*this, m_callback_baton);
274-
return true;
275302
}
276-
return false;
303+
Notify(notify);
304+
return true;
277305
}
278306

279307
bool PathMappingList::Remove(ConstString path, bool notify) {
280-
std::lock_guard<std::recursive_mutex> lock(m_mutex);
281-
iterator pos = FindIteratorForPath(path);
282-
if (pos != m_pairs.end()) {
308+
{
309+
std::lock_guard<std::mutex> lock(m_pairs_mutex);
310+
iterator pos = FindIteratorForPath(path);
311+
if (pos == m_pairs.end())
312+
return false;
313+
283314
++m_mod_id;
284315
m_pairs.erase(pos);
285-
if (notify && m_callback)
286-
m_callback(*this, m_callback_baton);
287-
return true;
288316
}
289-
return false;
317+
Notify(notify);
318+
return true;
290319
}
291320

292321
PathMappingList::const_iterator
293322
PathMappingList::FindIteratorForPath(ConstString path) const {
294-
std::lock_guard<std::recursive_mutex> lock(m_mutex);
323+
std::lock_guard<std::mutex> lock(m_pairs_mutex);
295324
const_iterator pos;
296325
const_iterator begin = m_pairs.begin();
297326
const_iterator end = m_pairs.end();
@@ -305,7 +334,7 @@ PathMappingList::FindIteratorForPath(ConstString path) const {
305334

306335
PathMappingList::iterator
307336
PathMappingList::FindIteratorForPath(ConstString path) {
308-
std::lock_guard<std::recursive_mutex> lock(m_mutex);
337+
std::lock_guard<std::mutex> lock(m_pairs_mutex);
309338
iterator pos;
310339
iterator begin = m_pairs.begin();
311340
iterator end = m_pairs.end();
@@ -319,7 +348,7 @@ PathMappingList::FindIteratorForPath(ConstString path) {
319348

320349
bool PathMappingList::GetPathsAtIndex(uint32_t idx, ConstString &path,
321350
ConstString &new_path) const {
322-
std::lock_guard<std::recursive_mutex> lock(m_mutex);
351+
std::lock_guard<std::mutex> lock(m_pairs_mutex);
323352
if (idx < m_pairs.size()) {
324353
path = m_pairs[idx].first;
325354
new_path = m_pairs[idx].second;
@@ -328,9 +357,9 @@ bool PathMappingList::GetPathsAtIndex(uint32_t idx, ConstString &path,
328357
return false;
329358
}
330359

331-
uint32_t PathMappingList::FindIndexForPath(llvm::StringRef orig_path) const {
360+
uint32_t
361+
PathMappingList::FindIndexForPathNoLock(llvm::StringRef orig_path) const {
332362
const ConstString path = ConstString(NormalizePath(orig_path));
333-
std::lock_guard<std::recursive_mutex> lock(m_mutex);
334363
const_iterator pos;
335364
const_iterator begin = m_pairs.begin();
336365
const_iterator end = m_pairs.end();

0 commit comments

Comments
 (0)