@@ -290,18 +290,22 @@ static void saveThinArchiveToRepro(ArchiveFile const *file) {
290290}
291291
292292struct DeferredFile {
293+ #if LLVM_ENABLE_THREADS
293294 StringRef path;
294295 bool isLazy;
295296 MemoryBufferRef buffer;
297+ #endif
296298};
297299using DeferredFiles = std::vector<DeferredFile>;
298300
301+ #if LLVM_ENABLE_THREADS
299302class SerialBackgroundQueue {
300303 std::deque<std::function<void ()>> queue;
301304 std::thread *running;
302305 std::mutex mutex;
303306
304307public:
308+ bool stopAllWork = false ;
305309 void queueWork (std::function<void ()> work) {
306310 mutex.lock ();
307311 if (running && queue.empty ()) {
@@ -316,7 +320,7 @@ class SerialBackgroundQueue {
316320 queue.emplace_back (std::move (work));
317321 if (!running)
318322 running = new std::thread ([&]() {
319- while (true ) {
323+ while (!stopAllWork ) {
320324 mutex.lock ();
321325 if (queue.empty ()) {
322326 mutex.unlock ();
@@ -335,6 +339,8 @@ class SerialBackgroundQueue {
335339 }
336340};
337341
342+ static SerialBackgroundQueue pageInQueue;
343+
338344// Most input files have been mapped but not yet paged in.
339345// This code forces the page-ins on multiple threads so
340346// the process is not stalled waiting on disk buffer i/o.
@@ -356,8 +362,8 @@ void multiThreadedPageInBackground(DeferredFiles &deferred) {
356362
357363#if _WIN32
358364 // 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) {
365+ for (const char *page = buff.data (), *end = page + buff.size ();
366+ page < end && !pageInQueue. stopAllWork ; page += pageSize) {
361367 LLVM_ATTRIBUTE_UNUSED volatile char t = *page;
362368 (void )t;
363369 }
@@ -370,24 +376,19 @@ void multiThreadedPageInBackground(DeferredFiles &deferred) {
370376#endif
371377 };
372378
373- #if LLVM_ENABLE_THREADS
374379 { // Create scope for waiting for the taskGroup
375380 std::atomic_size_t index = 0 ;
376381 llvm::parallel::TaskGroup taskGroup;
377382 for (int w = 0 ; w < config->readWorkers ; w++)
378383 taskGroup.spawn ([&index, &preloadDeferredFile, &deferred]() {
379- while (true ) {
384+ while (!pageInQueue. stopAllWork ) {
380385 size_t localIndex = index.fetch_add (1 );
381386 if (localIndex >= deferred.size ())
382387 break ;
383388 preloadDeferredFile (deferred[localIndex]);
384389 }
385390 });
386391 }
387- #else
388- for (const auto &file : deferred)
389- preloadDeferredFile (file);
390- #endif
391392
392393 auto dt = high_resolution_clock::now () - t0;
393394 if (Process::GetEnv (" LLD_MULTI_THREAD_PAGE" ))
@@ -397,12 +398,12 @@ void multiThreadedPageInBackground(DeferredFiles &deferred) {
397398}
398399
399400static void multiThreadedPageIn (const DeferredFiles &deferred) {
400- static SerialBackgroundQueue pageInQueue;
401401 pageInQueue.queueWork ([=]() {
402402 DeferredFiles files = deferred;
403403 multiThreadedPageInBackground (files);
404404 });
405405}
406+ #endif
406407
407408static InputFile *processFile (std::optional<MemoryBufferRef> buffer,
408409 DeferredFiles *archiveContents, StringRef path,
@@ -502,8 +503,10 @@ static InputFile *processFile(std::optional<MemoryBufferRef> buffer,
502503 continue ;
503504 }
504505
506+ #if LLVM_ENABLE_THREADS
505507 if (archiveContents)
506508 archiveContents->push_back ({path, isLazy, *mb});
509+ #endif
507510 if (!hasObjCSection (*mb))
508511 continue ;
509512 if (Error e = file->fetch (c, " -ObjC" ))
@@ -579,9 +582,11 @@ static void deferFile(StringRef path, bool isLazy, DeferredFiles &deferred) {
579582 std::optional<MemoryBufferRef> buffer = readFile (path);
580583 if (!buffer)
581584 return ;
585+ #if LLVM_ENABLE_THREADS
582586 if (config->readWorkers )
583587 deferred.push_back ({path, isLazy, *buffer});
584588 else
589+ #endif
585590 processFile (buffer, nullptr , path, LoadType::CommandLine, isLazy);
586591}
587592
@@ -1443,6 +1448,7 @@ static void createFiles(const InputArgList &args) {
14431448 }
14441449 }
14451450
1451+ #if LLVM_ENABLE_THREADS
14461452 if (config->readWorkers ) {
14471453 multiThreadedPageIn (deferredFiles);
14481454
@@ -1459,7 +1465,10 @@ static void createFiles(const InputArgList &args) {
14591465 multiThreadedPageIn (archiveContents);
14601466 for (auto *archive : archives)
14611467 archive->addLazySymbols ();
1468+
1469+ pageInQueue.stopAllWork = true ;
14621470 }
1471+ #endif
14631472}
14641473
14651474static void gatherInputSections () {
@@ -1847,13 +1856,17 @@ bool link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS,
18471856 }
18481857
18491858 if (auto *arg = args.getLastArg (OPT_read_workers)) {
1859+ #if LLVM_ENABLE_THREADS
18501860 StringRef v (arg->getValue ());
18511861 unsigned workers = 0 ;
18521862 if (!llvm::to_integer (v, workers, 0 ))
18531863 error (arg->getSpelling () +
18541864 " : expected a non-negative integer, but got '" + arg->getValue () +
18551865 " '" );
18561866 config->readWorkers = workers;
1867+ #else
1868+ error (arg->getSpelling () + " : option unavailable" );
1869+ #endif
18571870 }
18581871 if (auto *arg = args.getLastArg (OPT_threads_eq)) {
18591872 StringRef v (arg->getValue ());
0 commit comments