Skip to content

Commit 5a39e60

Browse files
committed
Pre-empt read-worker threads.
1 parent 13dcdec commit 5a39e60

File tree

1 file changed

+19
-10
lines changed

1 file changed

+19
-10
lines changed

lld/MachO/Driver.cpp

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -296,12 +296,14 @@ struct DeferredFile {
296296
};
297297
using DeferredFiles = std::vector<DeferredFile>;
298298

299+
#if LLVM_ENABLE_THREADS
299300
class SerialBackgroundQueue {
300301
std::deque<std::function<void()>> queue;
301302
std::thread *running;
302303
std::mutex mutex;
303304

304305
public:
306+
bool stopAllWork = false;
305307
void queueWork(std::function<void()> work) {
306308
mutex.lock();
307309
if (running && queue.empty()) {
@@ -316,7 +318,7 @@ class SerialBackgroundQueue {
316318
queue.emplace_back(std::move(work));
317319
if (!running)
318320
running = new std::thread([&]() {
319-
while (true) {
321+
while (!stopAllWork) {
320322
mutex.lock();
321323
if (queue.empty()) {
322324
mutex.unlock();
@@ -335,6 +337,8 @@ class SerialBackgroundQueue {
335337
}
336338
};
337339

340+
static SerialBackgroundQueue pageInQueue;
341+
338342
// Most input files have been mapped but not yet paged in.
339343
// This code forces the page-ins on multiple threads so
340344
// the process is not stalled waiting on disk buffer i/o.
@@ -356,8 +360,8 @@ void multiThreadedPageInBackground(DeferredFiles &deferred) {
356360

357361
#if _WIN32
358362
// Reference all file's mmap'd pages to load them into memory.
359-
for (const char *page = buff.data(), *end = page + buff.size(); page < end;
360-
page += pageSize) {
363+
for (const char *page = buff.data(), *end = page + buff.size();
364+
page < end && !pageInQueue.stopAllWork; page += pageSize) {
361365
LLVM_ATTRIBUTE_UNUSED volatile char t = *page;
362366
(void)t;
363367
}
@@ -370,24 +374,19 @@ void multiThreadedPageInBackground(DeferredFiles &deferred) {
370374
#endif
371375
};
372376

373-
#if LLVM_ENABLE_THREADS
374377
{ // Create scope for waiting for the taskGroup
375378
std::atomic_size_t index = 0;
376379
llvm::parallel::TaskGroup taskGroup;
377380
for (int w = 0; w < config->readWorkers; w++)
378381
taskGroup.spawn([&index, &preloadDeferredFile, &deferred]() {
379-
while (true) {
382+
while (!pageInQueue.stopAllWork) {
380383
size_t localIndex = index.fetch_add(1);
381384
if (localIndex >= deferred.size())
382385
break;
383386
preloadDeferredFile(deferred[localIndex]);
384387
}
385388
});
386389
}
387-
#else
388-
for (const auto &file : deferred)
389-
preloadDeferredFile(file);
390-
#endif
391390

392391
auto dt = high_resolution_clock::now() - t0;
393392
if (Process::GetEnv("LLD_MULTI_THREAD_PAGE"))
@@ -397,12 +396,12 @@ void multiThreadedPageInBackground(DeferredFiles &deferred) {
397396
}
398397

399398
static void multiThreadedPageIn(const DeferredFiles &deferred) {
400-
static SerialBackgroundQueue pageInQueue;
401399
pageInQueue.queueWork([=]() {
402400
DeferredFiles files = deferred;
403401
multiThreadedPageInBackground(files);
404402
});
405403
}
404+
#endif
406405

407406
static InputFile *processFile(std::optional<MemoryBufferRef> buffer,
408407
DeferredFiles *archiveContents, StringRef path,
@@ -579,9 +578,11 @@ static void deferFile(StringRef path, bool isLazy, DeferredFiles &deferred) {
579578
std::optional<MemoryBufferRef> buffer = readFile(path);
580579
if (!buffer)
581580
return;
581+
#if LLVM_ENABLE_THREADS
582582
if (config->readWorkers)
583583
deferred.push_back({path, isLazy, *buffer});
584584
else
585+
#endif
585586
processFile(buffer, nullptr, path, LoadType::CommandLine, isLazy);
586587
}
587588

@@ -1443,6 +1444,7 @@ static void createFiles(const InputArgList &args) {
14431444
}
14441445
}
14451446

1447+
#if LLVM_ENABLE_THREADS
14461448
if (config->readWorkers) {
14471449
multiThreadedPageIn(deferredFiles);
14481450

@@ -1459,7 +1461,10 @@ static void createFiles(const InputArgList &args) {
14591461
multiThreadedPageIn(archiveContents);
14601462
for (auto *archive : archives)
14611463
archive->addLazySymbols();
1464+
1465+
pageInQueue.stopAllWork = true;
14621466
}
1467+
#endif
14631468
}
14641469

14651470
static void gatherInputSections() {
@@ -1847,13 +1852,17 @@ bool link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS,
18471852
}
18481853

18491854
if (auto *arg = args.getLastArg(OPT_read_workers)) {
1855+
#if LLVM_ENABLE_THREADS
18501856
StringRef v(arg->getValue());
18511857
unsigned workers = 0;
18521858
if (!llvm::to_integer(v, workers, 0))
18531859
error(arg->getSpelling() +
18541860
": expected a non-negative integer, but got '" + arg->getValue() +
18551861
"'");
18561862
config->readWorkers = workers;
1863+
#else
1864+
error(arg->getSpelling() + ": option unavailable");
1865+
#endif
18571866
}
18581867
if (auto *arg = args.getLastArg(OPT_threads_eq)) {
18591868
StringRef v(arg->getValue());

0 commit comments

Comments
 (0)