<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body><div>On Mon, Dec 7, 2015, at 04:55 AM, Joakim Hassila via swift-corelibs-dev wrote:<br></div>
<blockquote><div>Secondly, we have extended the public libdispatch API internally with one<br></div>
<div>more flavor of dispatching, let’s call it ‘dispatch_async_inline’ - the<br></div>
<div>semantics being ‘perform the processing of the work synchronously if we<br></div>
<div>wouldn’t block the calling thread, if we would block, instead perform the<br></div>
<div>work as a normal dispatch_async’.<br></div>
<div> </div>
<div>Would such a change be considered to be integrated, or should we keep our<br></div>
<div>internal diffs indefinitely? Just to understand if it is worth the effort<br></div>
<div>with a nicely packaged pull request or not...<br></div>
<div> </div>
<div>The rationale for the API is that we are quite latency sensitive and want<br></div>
<div>to use inline processing up until the point where we can’t keep up with<br></div>
<div>the available work, at which point we would switch to asynchronous<br></div>
<div>processing seamlessly (we have multiple producers). This means that the<br></div>
<div>thread calling this API can be stolen for a significant amount of time<br></div>
<div>(emptying the queue it was assigned to), but when the system is under<br></div>
<div>‘light' load, we don’t need to incur the wakeup penalty for a completely<br></div>
<div>asynchronous dispatch.<br></div>
</blockquote><div> </div>
<div>I actually have an outstanding radar asking for this exact functionality. My proposal called it `dispatch_try_sync()`, which didn't actually call the dispatch_async() automatically but simply returned a boolean value telling you if it ran the code. My use-case here wasn't actually that I wanted to run the code async, but that I needed to do two operations on a realtime thread in any order, one of which needed to be on a queue, so I wanted to do something like<br></div>
<div> </div>
<div><span class="font" style="font-family: menlo, consolas, "courier new", monospace, sans-serif;">BOOL done = dispatch_try_sync(queue, ^{ ... });</span><span class="font" style="font-family: menlo, consolas, "courier new", monospace, sans-serif;"><br></span></div>
<div><span class="font" style="font-family: menlo, consolas, "courier new", monospace, sans-serif;">do_other_work();</span><span class="font" style="font-family: menlo, consolas, "courier new", monospace, sans-serif;"><br></span></div>
<div><span class="font" style="font-family: menlo, consolas, "courier new", monospace, sans-serif;">if (!done) {</span><span class="font" style="font-family: menlo, consolas, "courier new", monospace, sans-serif;"><br></span></div>
<div><span class="font" style="font-family: menlo, consolas, "courier new", monospace, sans-serif;"> dispatch_sync(queue, ^{ ... });</span><span class="font" style="font-family: menlo, consolas, "courier new", monospace, sans-serif;"><br></span></div>
<div><span class="font" style="font-family: menlo, consolas, "courier new", monospace, sans-serif;">}</span><span class="font" style="font-family: menlo, consolas, "courier new", monospace, sans-serif;"><br></span></div>
<div> </div>
<div>My radar is still open (rdar://problem/16436943), but it got a response as follows:<br></div>
<div> </div>
<blockquote><div>I think the best way to "emulate" this is to use a DATA_OR source, and not semaphores or other things like that.<br></div>
<div> </div>
<div>Most of the issues that I've seen with trylock() tends to be uses looking like this:<br></div>
<div> </div>
<div><span class="font" style="font-family: menlo, consolas, "courier new", monospace, sans-serif;">again:</span><span class="font" style="font-family: menlo, consolas, "courier new", monospace, sans-serif;"><br></span></div>
<div><span class="font" style="font-family: menlo, consolas, "courier new", monospace, sans-serif;"> if (trylock()) {</span><span class="font" style="font-family: menlo, consolas, "courier new", monospace, sans-serif;"><br></span></div>
<div><span class="font" style="font-family: menlo, consolas, "courier new", monospace, sans-serif;"> do {</span><span class="font" style="font-family: menlo, consolas, "courier new", monospace, sans-serif;"><br></span></div>
<div><span class="font" style="font-family: menlo, consolas, "courier new", monospace, sans-serif;"> clear_marker();</span><span class="font" style="font-family: menlo, consolas, "courier new", monospace, sans-serif;"><br></span></div>
<div><span class="font" style="font-family: menlo, consolas, "courier new", monospace, sans-serif;"> do_job();</span><span class="font" style="font-family: menlo, consolas, "courier new", monospace, sans-serif;"><br></span></div>
<div><span class="font" style="font-family: menlo, consolas, "courier new", monospace, sans-serif;"> } while(has_marker());</span><span class="font" style="font-family: menlo, consolas, "courier new", monospace, sans-serif;"><br></span></div>
<div><span class="font" style="font-family: menlo, consolas, "courier new", monospace, sans-serif;"> unlock();</span><span class="font" style="font-family: menlo, consolas, "courier new", monospace, sans-serif;"><br></span></div>
<div><span class="font" style="font-family: menlo, consolas, "courier new", monospace, sans-serif;"> } else if (!has_marker()) {</span><span class="font" style="font-family: menlo, consolas, "courier new", monospace, sans-serif;"><br></span></div>
<div><span class="font" style="font-family: menlo, consolas, "courier new", monospace, sans-serif;"> set_marker();</span><span class="font" style="font-family: menlo, consolas, "courier new", monospace, sans-serif;"><br></span></div>
<div><span class="font" style="font-family: menlo, consolas, "courier new", monospace, sans-serif;"> goto again;</span><span class="font" style="font-family: menlo, consolas, "courier new", monospace, sans-serif;"><br></span></div>
<div><span class="font" style="font-family: menlo, consolas, "courier new", monospace, sans-serif;"> }</span><span class="font" style="font-family: menlo, consolas, "courier new", monospace, sans-serif;"><br></span></div>
<div> </div>
<div>and all unlockers check for the marker to do the said job before unlock basically.<br></div>
<div> </div>
<div>The thing is, most of the people use that wrongly and don't loop properly making those coalescing checks racy, that's what dispatch DATA_OR sources are for.<br></div>
<div> </div>
<div>Many other uses can also be replaced with a dispatch_async()<br></div>
<div> </div>
<div>and it's very clear that the reporter can do exactly what he wants with a DATA_OR source. We should have a way to make sources acts as barriers (which I have a patch for) else we only provide half the required primitives.<br></div>
<div> </div>
<div>I don't see a compelling use case that can't be solved elegantly with data sources today.<br></div>
<div> </div>
<div>Using a DISPATCH_SOURCE_DATA_OR with a latch is a good alternative to what you are doing.<br></div>
<div> </div>
<div>We are continuing to work on this issue, and will follow up with you again.<br></div>
</blockquote><div> </div>
<div>-Kevin Ballard<br></div>
</body>
</html>