Chromium Code Reviews| Index: src/IceGlobalContext.cpp |
| diff --git a/src/IceGlobalContext.cpp b/src/IceGlobalContext.cpp |
| index d353bfe3874352d9ee789a218c84c5ab5a115634..92a5d5ae41f140e3ab4bf577fe2a3d27565aa813 100644 |
| --- a/src/IceGlobalContext.cpp |
| +++ b/src/IceGlobalContext.cpp |
| @@ -218,6 +218,41 @@ public: |
| UndefPool Undefs; |
| }; |
| +void GlobalContext::waitForWorkerThreads() { |
| + { // Make sure we wait at most once. |
| + std::unique_lock<GlobalLockType> L(WaitForWorkersLock); |
|
Jim Stichnoth
2016/03/25 04:31:04
Our new super-awesome coding style would name this
Karl
2016/03/29 17:35:02
Removed, went with atomic_bool.
|
| + if (WaitForWorkerThreadsCalled) |
|
Jim Stichnoth
2016/03/25 04:31:04
It seems that WaitForWorkerThreadsCalled could act
Karl
2016/03/29 17:35:02
Changed to atomic_bool.
|
| + return; |
| + WaitForWorkerThreadsCalled = true; |
| + } |
| + optQueueNotifyEnd(); |
| + for (std::thread &Worker : TranslationThreads) { |
| + Worker.join(); |
| + } |
| + TranslationThreads.clear(); |
| + |
| + // Only notify the emit queue to end after all the translation threads have |
| + // ended. |
| + emitQueueNotifyEnd(); |
| + for (std::thread &Worker : EmitterThreads) { |
| + Worker.join(); |
| + } |
| + EmitterThreads.clear(); |
| + |
| + if (BuildDefs::timers()) { |
| + auto Timers = getTimers(); |
| + for (ThreadContext *TLS : AllThreadContexts) |
| + Timers->mergeFrom(TLS->Timers); |
| + } |
| + if (BuildDefs::dump()) { |
| + // Do a separate loop over AllThreadContexts to avoid holding two locks |
| + // at once. |
| + auto Stats = getStatsCumulative(); |
| + for (ThreadContext *TLS : AllThreadContexts) |
| + Stats->add(TLS->StatsCumulative); |
| + } |
| +} |
| + |
| void GlobalContext::CodeStats::dump(const IceString &Name, GlobalContext *Ctx) { |
| if (!BuildDefs::dump()) |
| return; |
| @@ -256,7 +291,10 @@ GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError, |
| : ConstPool(new ConstantPool()), ErrorStatus(), StrDump(OsDump), |
| StrEmit(OsEmit), StrError(OsError), ObjectWriter(), |
| OptQ(/*Sequential=*/Flags.isSequential(), |
| - /*MaxSize=*/Flags.getNumTranslationThreads()), |
| + /*MaxSize=*/ |
| + (Flags.getParseParallel() && Flags.getBuildOnRead()) |
| + ? MaxOptQSize |
| + : Flags.getNumTranslationThreads()), |
| // EmitQ is allowed unlimited size. |
| EmitQ(/*Sequential=*/Flags.isSequential()), |
| DataLowering(TargetDataLowering::createLowering(this)) { |
| @@ -309,7 +347,8 @@ GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError, |
| void GlobalContext::translateFunctions() { |
| TimerMarker Timer(TimerStack::TT_translateFunctions, this); |
| - while (std::unique_ptr<Cfg> Func = optQueueBlockingPop()) { |
| + while (std::unique_ptr<OptWorkItem> OptItem = optQueueBlockingPop()) { |
| + std::unique_ptr<Cfg> Func = OptItem->getParsedCfg(); |
| // Install Func in TLS for Cfg-specific container allocators. |
| CfgLocalAllocatorScope _(Func.get()); |
| // Reset per-function stats being accumulated in TLS. |
| @@ -867,19 +906,19 @@ void GlobalContext::setTimerName(TimerStackIdT StackID, |
| // interface to take and transfer ownership, but they internally store the raw |
| // Cfg pointer in the work queue. This allows e.g. future queue optimizations |
| // such as the use of atomics to modify queue elements. |
| -void GlobalContext::optQueueBlockingPush(std::unique_ptr<Cfg> Func) { |
| - assert(Func); |
| +void GlobalContext::optQueueBlockingPush(std::unique_ptr<OptWorkItem> Item) { |
| + assert(Item); |
| { |
| TimerMarker _(TimerStack::TT_qTransPush, this); |
| - OptQ.blockingPush(std::move(Func)); |
| + OptQ.blockingPush(std::move(Item)); |
| } |
| if (getFlags().isSequential()) |
| translateFunctions(); |
| } |
| -std::unique_ptr<Cfg> GlobalContext::optQueueBlockingPop() { |
| +std::unique_ptr<OptWorkItem> GlobalContext::optQueueBlockingPop() { |
| TimerMarker _(TimerStack::TT_qTransPop, this); |
| - return std::unique_ptr<Cfg>(OptQ.blockingPop()); |
| + return std::unique_ptr<OptWorkItem>(OptQ.blockingPop()); |
| } |
| void GlobalContext::emitQueueBlockingPush( |