@@ -296,12 +296,14 @@ struct DeferredFile {
296
296
};
297
297
using DeferredFiles = std::vector<DeferredFile>;
298
298
299
+ #if LLVM_ENABLE_THREADS
299
300
class SerialBackgroundQueue {
300
301
std::deque<std::function<void ()>> queue;
301
302
std::thread *running;
302
303
std::mutex mutex;
303
304
304
305
public:
306
+ bool stopAllWork = false ;
305
307
void queueWork (std::function<void ()> work) {
306
308
mutex.lock ();
307
309
if (running && queue.empty ()) {
@@ -316,7 +318,7 @@ class SerialBackgroundQueue {
316
318
queue.emplace_back (std::move (work));
317
319
if (!running)
318
320
running = new std::thread ([&]() {
319
- while (true ) {
321
+ while (!stopAllWork ) {
320
322
mutex.lock ();
321
323
if (queue.empty ()) {
322
324
mutex.unlock ();
@@ -335,6 +337,8 @@ class SerialBackgroundQueue {
335
337
}
336
338
};
337
339
340
+ static SerialBackgroundQueue pageInQueue;
341
+
338
342
// Most input files have been mapped but not yet paged in.
339
343
// This code forces the page-ins on multiple threads so
340
344
// the process is not stalled waiting on disk buffer i/o.
@@ -356,8 +360,8 @@ void multiThreadedPageInBackground(DeferredFiles &deferred) {
356
360
357
361
#if _WIN32
358
362
// 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) {
361
365
LLVM_ATTRIBUTE_UNUSED volatile char t = *page;
362
366
(void )t;
363
367
}
@@ -370,24 +374,19 @@ void multiThreadedPageInBackground(DeferredFiles &deferred) {
370
374
#endif
371
375
};
372
376
373
- #if LLVM_ENABLE_THREADS
374
377
{ // Create scope for waiting for the taskGroup
375
378
std::atomic_size_t index = 0 ;
376
379
llvm::parallel::TaskGroup taskGroup;
377
380
for (int w = 0 ; w < config->readWorkers ; w++)
378
381
taskGroup.spawn ([&index, &preloadDeferredFile, &deferred]() {
379
- while (true ) {
382
+ while (!pageInQueue. stopAllWork ) {
380
383
size_t localIndex = index.fetch_add (1 );
381
384
if (localIndex >= deferred.size ())
382
385
break ;
383
386
preloadDeferredFile (deferred[localIndex]);
384
387
}
385
388
});
386
389
}
387
- #else
388
- for (const auto &file : deferred)
389
- preloadDeferredFile (file);
390
- #endif
391
390
392
391
auto dt = high_resolution_clock::now () - t0;
393
392
if (Process::GetEnv (" LLD_MULTI_THREAD_PAGE" ))
@@ -397,12 +396,12 @@ void multiThreadedPageInBackground(DeferredFiles &deferred) {
397
396
}
398
397
399
398
static void multiThreadedPageIn (const DeferredFiles &deferred) {
400
- static SerialBackgroundQueue pageInQueue;
401
399
pageInQueue.queueWork ([=]() {
402
400
DeferredFiles files = deferred;
403
401
multiThreadedPageInBackground (files);
404
402
});
405
403
}
404
+ #endif
406
405
407
406
static InputFile *processFile (std::optional<MemoryBufferRef> buffer,
408
407
DeferredFiles *archiveContents, StringRef path,
@@ -579,9 +578,11 @@ static void deferFile(StringRef path, bool isLazy, DeferredFiles &deferred) {
579
578
std::optional<MemoryBufferRef> buffer = readFile (path);
580
579
if (!buffer)
581
580
return ;
581
+ #if LLVM_ENABLE_THREADS
582
582
if (config->readWorkers )
583
583
deferred.push_back ({path, isLazy, *buffer});
584
584
else
585
+ #endif
585
586
processFile (buffer, nullptr , path, LoadType::CommandLine, isLazy);
586
587
}
587
588
@@ -1443,6 +1444,7 @@ static void createFiles(const InputArgList &args) {
1443
1444
}
1444
1445
}
1445
1446
1447
+ #if LLVM_ENABLE_THREADS
1446
1448
if (config->readWorkers ) {
1447
1449
multiThreadedPageIn (deferredFiles);
1448
1450
@@ -1459,7 +1461,10 @@ static void createFiles(const InputArgList &args) {
1459
1461
multiThreadedPageIn (archiveContents);
1460
1462
for (auto *archive : archives)
1461
1463
archive->addLazySymbols ();
1464
+
1465
+ pageInQueue.stopAllWork = true ;
1462
1466
}
1467
+ #endif
1463
1468
}
1464
1469
1465
1470
static void gatherInputSections () {
@@ -1847,13 +1852,17 @@ bool link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS,
1847
1852
}
1848
1853
1849
1854
if (auto *arg = args.getLastArg (OPT_read_workers)) {
1855
+ #if LLVM_ENABLE_THREADS
1850
1856
StringRef v (arg->getValue ());
1851
1857
unsigned workers = 0 ;
1852
1858
if (!llvm::to_integer (v, workers, 0 ))
1853
1859
error (arg->getSpelling () +
1854
1860
" : expected a non-negative integer, but got '" + arg->getValue () +
1855
1861
" '" );
1856
1862
config->readWorkers = workers;
1863
+ #else
1864
+ error (arg->getSpelling () + " : option unavailable" );
1865
+ #endif
1857
1866
}
1858
1867
if (auto *arg = args.getLastArg (OPT_threads_eq)) {
1859
1868
StringRef v (arg->getValue ());
0 commit comments