<div dir="ltr">I reverted my change so that there's no nested parallel_for_each calls in lld.<div><br></div><div>We should fix ThreadPoolExecutor so that it can be called from nested loops. Quote from <a href="https://bugs.llvm.org/show_bug.cgi?id=34806#c10">https://bugs.llvm.org/show_bug.cgi?id=34806#c10</a></div><div class="gmail_extra"><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div class="gmail_extra"><div class="gmail_extra">So, orthogonal to what is the best way to achieve a maximum performance in lld, I think ThreadPoolExecutor should be able to handle nested calls. It's because something that is not composable is hard to use. In general, when we call some function, we don't know/care about whether the function uses ThreadPoolExecutor or not. That belongs to an internal design of the function and shouldn't leak.</div></div></blockquote><div class="gmail_extra"><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Oct 6, 2017 at 10:09 AM, Evgeny Leviant <span dir="ltr"><<a href="mailto:eleviant@accesssoftek.com" target="_blank">eleviant@accesssoftek.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">




<div dir="ltr" style="font-size:12pt;color:rgb(0,0,0);background-color:rgb(255,255,255);font-family:Calibri,Arial,Helvetica,sans-serif">
<p>Recently added ThreadPoolExecutor limits number of worker threads to number of logical processors.<br>
</p>
<p>This might cause deadlock in case one's doing nested calls to parallel_for_each, like this:<br>
</p>
<p><br>
</p>
<p>void Bar() { ... <span style="font-size:12pt">}</span></p>
<p><br>
</p>
<p>void Foo() {<br>
</p>
<p>    parallel_for_each(Begin, End, Bar);<br>
</p>
<p>}</p>
<p><br>
</p>
<p>void main() {<br>
</p>
<p>  parallel_for_each(Begin, End, Foo);<br>
</p>
<p>}<br>
</p>
<p><br>
</p>
<p>This happens because both parallel_for_each and parallel_for_each_n wait for task group to finish<br>
</p>
<p>and this may actually never happen in case they're executed from worker threads. In such case worker</p>
<p>thread is blocked in TaskGroup destructor. This does happen <span style="font-size:12pt">in lld, when it writes output sections as </span></p>
<p><span style="font-size:12pt">th</span><span style="font-size:12pt">ere is a nested call to parallel_for_each_n to write each </span><span style="font-size:12pt">output section inputs.</span><span style="font-size:12pt"> </span></p>
</div>

</blockquote></div><br></div></div>