Skip to content

Commit 817036b

Browse files
committed
Second review.
1 parent 55e26a8 commit 817036b

File tree

1 file changed

+60
-59
lines changed

1 file changed

+60
-59
lines changed

lld/MachO/Driver.cpp

Lines changed: 60 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -288,71 +288,72 @@ class DeferredFile {
288288
public:
289289
StringRef path;
290290
bool isLazy;
291-
std::optional<MemoryBufferRef> buffer;
292-
const char *start;
293-
size_t size;
291+
MemoryBufferRef buffer;
294292
};
295293
using DeferredFiles = std::vector<DeferredFile>;
296294

297-
class PageInState {
298-
DeferredFiles deferred;
299-
size_t counter = 0, total = 0, pageSize;
300-
std::mutex mutex, *busy;
295+
// Most input files have been mapped but not yet paged in.
296+
// This code forces the page-ins on multiple threads so
297+
// the process is not stalled waiting on disk buffer i/o.
298+
void multiThreadedPageInBackground(const DeferredFiles &deferred) {
299+
static size_t pageSize = Process::getPageSizeEstimate(), totalBytes;
300+
size_t index = 0;
301+
std::mutex mutex;
302+
303+
parallelFor(0, config->readThreads, [&](size_t I) {
304+
while (true) {
305+
mutex.lock();
306+
if (index >= deferred.size()) {
307+
mutex.unlock();
308+
return;
309+
}
310+
const StringRef &buff = deferred[index].buffer.getBuffer();
311+
totalBytes += buff.size();
312+
index += 1;
313+
mutex.unlock();
314+
315+
volatile int t = 0; // Reference each page to load it into memory.
316+
for (const char *page = buff.data(), *end = page + buff.size();
317+
page < end; page += pageSize)
318+
t += *page;
319+
}
320+
});
301321

302-
public:
303-
PageInState(DeferredFiles &deferred, std::mutex *busy) {
304-
this->deferred = deferred;
305-
this->busy = busy;
306-
pageSize = llvm::sys::Process::getPageSizeEstimate();
307-
}
322+
if (getenv("LLD_MULTI_THREAD_PAGE"))
323+
llvm::dbgs() << "multiThreadedPageIn " << totalBytes << "/"
324+
<< deferred.size() << "\n";
325+
}
326+
327+
static void multiThreadedPageIn(const DeferredFiles &deferred) {
328+
static std::thread *running;
329+
static std::mutex mutex;
330+
static std::deque<DeferredFiles *> queue;
308331

309-
// Most input files have been mapped but not yet paged in.
310-
// This code forces the page-ins on multiple threads so
311-
// the process is not stalled waiting on disk buffer i/o.
312-
void multiThreadedPageInBackground() {
313-
static size_t totalBytes;
332+
mutex.lock();
333+
if (running) {
334+
running->join();
335+
delete running;
336+
running = nullptr;
337+
}
314338

315-
parallelFor(0, config->readThreads, [&](size_t I) {
339+
if (!deferred.empty()) {
340+
queue.emplace_back(new DeferredFiles(deferred));
341+
running = new std::thread([&]() {
316342
while (true) {
317343
mutex.lock();
318-
if (counter >= deferred.size()) {
344+
if (queue.empty()) {
319345
mutex.unlock();
320346
return;
321347
}
322-
DeferredFile &file = deferred[counter];
323-
totalBytes += file.size;
324-
counter += 1;
348+
DeferredFiles *deferred = queue.front();
349+
queue.pop_front();
325350
mutex.unlock();
326-
327-
int t = 0; // Reference each page to load it into memory.
328-
for (const char *page = file.start, *end = page + file.size; page < end;
329-
page += pageSize)
330-
t += *page;
331-
total += t; // Avoids the loop being optimised out.
351+
multiThreadedPageInBackground(*deferred);
352+
delete deferred;
332353
}
333354
});
334-
335-
if (getenv("LLD_MULTI_THREAD_PAGE"))
336-
llvm::dbgs() << "multiThreadedPageIn " << totalBytes << "/"
337-
<< deferred.size() << "\n";
338-
339-
busy->unlock();
340-
delete this;
341355
}
342-
};
343-
344-
static void multiThreadedPageIn(DeferredFiles deferred) {
345-
static std::thread *running;
346-
static std::mutex busy;
347-
348-
busy.lock();
349-
if (running) {
350-
running->join();
351-
delete running;
352-
}
353-
354-
running = new std::thread(&PageInState::multiThreadedPageInBackground,
355-
new PageInState(deferred, &busy));
356+
mutex.unlock();
356357
}
357358

358359
static InputFile *processFile(std::optional<MemoryBufferRef> buffer,
@@ -454,9 +455,7 @@ static InputFile *processFile(std::optional<MemoryBufferRef> buffer,
454455
}
455456

456457
if (archiveContents)
457-
archiveContents->push_back({path, isLazy, std::nullopt,
458-
mb->getBuffer().data(),
459-
mb->getBuffer().size()});
458+
archiveContents->push_back({path, isLazy, *mb});
460459
if (!hasObjCSection(*mb))
461460
continue;
462461
if (Error e = file->fetch(c, "-ObjC"))
@@ -530,9 +529,10 @@ static InputFile *addFile(StringRef path, LoadType loadType,
530529

531530
static void deferFile(StringRef path, bool isLazy, DeferredFiles &deferred) {
532531
std::optional<MemoryBufferRef> buffer = readFile(path);
532+
if (!buffer)
533+
return;
533534
if (config->readThreads)
534-
deferred.push_back({path, isLazy, buffer, buffer->getBuffer().data(),
535-
buffer->getBuffer().size()});
535+
deferred.push_back({path, isLazy, *buffer});
536536
else
537537
processFile(buffer, nullptr, path, LoadType::CommandLine, isLazy);
538538
}
@@ -1400,11 +1400,12 @@ static void createFiles(const InputArgList &args) {
14001400

14011401
DeferredFiles archiveContents;
14021402
std::vector<ArchiveFile *> archives;
1403-
for (auto &file : deferredFiles)
1404-
if (ArchiveFile *archive = dyn_cast<ArchiveFile>(
1405-
processFile(file.buffer, &archiveContents, file.path,
1406-
LoadType::CommandLine, file.isLazy)))
1403+
for (auto &file : deferredFiles) {
1404+
auto inputFile = processFile(file.buffer, &archiveContents, file.path,
1405+
LoadType::CommandLine, file.isLazy);
1406+
if (ArchiveFile *archive = dyn_cast<ArchiveFile>(inputFile))
14071407
archives.push_back(archive);
1408+
}
14081409

14091410
if (!archiveContents.empty()) {
14101411
multiThreadedPageIn(archiveContents);

0 commit comments

Comments
 (0)