@@ -286,6 +286,8 @@ static void saveThinArchiveToRepro(ArchiveFile const *file) {
286286
287287class DeferredFile {
288288public:
289+ DeferredFile (StringRef path, bool isLazy, MemoryBufferRef buffer)
290+ : path(path), isLazy(isLazy), buffer(buffer) {}
289291 StringRef path;
290292 bool isLazy;
291293 MemoryBufferRef buffer;
@@ -297,36 +299,31 @@ using DeferredFiles = std::vector<DeferredFile>;
297299// the process is not stalled waiting on disk buffer i/o.
298300void multiThreadedPageInBackground (const DeferredFiles &deferred) {
299301 static const size_t pageSize = Process::getPageSizeEstimate ();
300- size_t totalBytes = 0 ;
301- static std::mutex mutex;
302- size_t index = 0 ;
302+ static size_t totalBytes = 0 ;
303+ std::atomic_int index = 0 ;
303304
304305 parallelFor (0 , config->readThreads , [&](size_t I) {
305- while (true ) {
306- mutex.lock ();
307- if (index >= deferred.size ()) {
308- mutex.unlock ();
309- return ;
310- }
306+ while (index < (int )deferred.size ()) {
311307 const StringRef &buff = deferred[index].buffer .getBuffer ();
312308 totalBytes += buff.size ();
313309 index += 1 ;
314- mutex.unlock ();
315310
316- // Reference each page to load it into memory.
311+ // Reference all file's mmap'd pages to load them into memory.
317312 for (const char *page = buff.data (), *end = page + buff.size ();
318313 page < end; page += pageSize)
319- [[maybe_unused]] volatile char t = *page;
314+ volatile char t = *page;
320315 }
321316 });
322317
318+ #ifndef NDEBUG
323319 if (getenv (" LLD_MULTI_THREAD_PAGE" ))
324320 llvm::dbgs () << " multiThreadedPageIn " << totalBytes << " /"
325321 << deferred.size () << " \n " ;
322+ #endif
326323}
327324
328325static void multiThreadedPageIn (const DeferredFiles &deferred) {
329- static std::deque<DeferredFiles * > queue;
326+ static std::deque<DeferredFiles> queue;
330327 static std::thread *running;
331328 static std::mutex mutex;
332329
@@ -340,21 +337,18 @@ static void multiThreadedPageIn(const DeferredFiles &deferred) {
340337 }
341338
342339 if (!deferred.empty ()) {
343- queue.emplace_back (new DeferredFiles ( deferred) );
340+ queue.emplace_back (deferred);
344341 if (!running)
345342 running = new std::thread ([&]() {
346- while (true ) {
343+ mutex.lock ();
344+ while (!queue.empty ()) {
345+ const DeferredFiles &deferred = queue.front ();
346+ mutex.unlock ();
347+ multiThreadedPageInBackground (deferred);
347348 mutex.lock ();
348- if (queue.empty ()) {
349- mutex.unlock ();
350- return ;
351- }
352- DeferredFiles *deferred = queue.front ();
353349 queue.pop_front ();
354- mutex.unlock ();
355- multiThreadedPageInBackground (*deferred);
356- delete deferred;
357350 }
351+ mutex.unlock ();
358352 });
359353 }
360354 mutex.unlock ();
@@ -459,7 +453,7 @@ static InputFile *processFile(std::optional<MemoryBufferRef> buffer,
459453 }
460454
461455 if (archiveContents)
462- archiveContents->push_back ({ path, isLazy, *mb} );
456+ archiveContents->emplace_back ( path, isLazy, *mb);
463457 if (!hasObjCSection (*mb))
464458 continue ;
465459 if (Error e = file->fetch (c, " -ObjC" ))
0 commit comments