diff options
Diffstat (limited to 'en/devices/architecture/hidl/threading.html')
-rw-r--r-- | en/devices/architecture/hidl/threading.html | 178 |
1 files changed, 0 insertions, 178 deletions
diff --git a/en/devices/architecture/hidl/threading.html b/en/devices/architecture/hidl/threading.html deleted file mode 100644 index fef555ad..00000000 --- a/en/devices/architecture/hidl/threading.html +++ /dev/null @@ -1,178 +0,0 @@ -<html devsite> - <head> - <title>Threading Models</title> - <meta name="project_path" value="/_project.yaml" /> - <meta name="book_path" value="/_book.yaml" /> - </head> - <body> - <!-- - Copyright 2017 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - --> - - -<p>Methods marked as <code>oneway</code> do not block. For methods not marked as -<code>oneway</code>, a client's method call will block until the server has -completed execution or called a synchronous callback (whichever comes first). -Server method implementations may call at most one synchronous callback; extra -callback calls are discarded and logged as errors. If a method is supposed to -return values via callback and does not call its callback, this is logged as an -error and reported as a transport error to the client.</p> - -<h2 id=passthrough>Threads in passthrough mode</h2> -<p>In passthrough mode, most calls are synchronous. However, to preserve the -intended behavior that <code>oneway</code> calls do not block the client, a -thread is created for each process. For details, see the -<a href="/devices/architecture/hidl/index.html#passthrough">HIDL overview</a>. -</p> - -<h2 id=binderized>Threads in binderized HALs</h2> -<p>To serve incoming RPC calls (including asynchronous callbacks from HALs to -HAL users) and death notifications, a threadpool is associated with each process -that uses HIDL. If a single process implements multiple HIDL interfaces and/or -death notification handlers, its threadpool is shared between all of them. When -a process receives an incoming method call from a client, it picks a free thread -from the threadpool and executes the call on that thread. If no free thread is -available, it blocks until one is available.</p> - -<p>If the server has only one thread, then calls into the server are completed -in order. A server with more than one thread may complete calls out of order -even if the client has only one thread. However, for a given interface object, -<code>oneway</code> calls are guaranteed to be ordered (see -<a href="#model">Server threading model</a>). For a multi-threaded server that -hosts multiple interfaces, <code>oneway</code> calls to different interfaces -may be processed concurrently with each other or other blocking calls.</p> - -<p>Multiple nested calls will be sent on the same hwbinder thread. For instance, -if a process (A) makes a synchronous call from a hwbinder thread into process (B), -and then process (B) makes a synchronous call back into process (A), the call will -be executed on the original hwbinder thread in (A) which is blocked on the original -call. This optimization makes it possible to have a single threaded server able to -handle nested calls, but it does not extend to cases where the calls travel through -another sequence of IPC calls. For instance, if process (B) had made a -binder/vndbinder call which called into a process (C) and then process (C) calls -back into (A), it cannot be served on the original thread in (A).</p> - -<h2 id=model>Server threading model</h2> -<p>Except for passthrough mode, server implementations of HIDL interfaces live -in a different process than the client and need one or more threads waiting for -incoming method calls. These threads are the server's threadpool; the server may -decide how many threads it wants running in its threadpool, and can use a -threadpool size of one to serialize all calls on its interfaces. If the server -has more than one thread in the threadpool, it can receive concurrent incoming -calls on any of its interfaces (in C++, this means that shared data must be -carefully locked).</p> - -<p>Oneway calls into the same interface are serialized. If a multi-threaded -client calls <code>method1</code> and <code>method2</code> on interface -<code>IFoo</code>, and <code>method3</code> on interface <code>IBar</code>, -<code>method1</code> and <code>method2</code> will always be serialized, but -<code>method3</code> may run in parallel with <code>method1</code> and -<code>method2</code>.</p> - -<p>A single client thread of execution can cause concurrent execution on a -server with multiple threads in two ways:</p> - -<ul> -<li><code>oneway</code> calls do not block. If a <code>oneway</code> call is -executed and then a non-<code>oneway</code> is called, the server may execute -the <code>oneway</code> call and the non-<code>oneway</code> call -simultaneously.</li> -<li>Server methods that pass data back with synchronous callbacks can unblock -the client as soon as the callback is called from the server.</li> -</ul> - -<p>For the second way, any code in the server function that executes after the -callback is called may execute concurrently, with the server handling subsequent -calls from the client. This includes code in the server function and automatic -destructors that execute at the end of the function. If the server has more than -one thread in its threadpool, concurrency issues arise even if calls are coming -in from only one single client thread. (If any HAL served by a process needs -multiple threads, all HALs will have multiple threads because the threadpool is -shared per-process.)</p> - -<p>As soon as the server calls the provided callback, the transport can call the -implemented callback on the client and unblock the client. The client proceeds -in parallel with whatever the server implementation does after it calls the -callback (which may include running destructors). Code in the server function -after the callback is no longer blocking the client (as long as the server -threadpool has enough threads to handle incoming calls), but may be executed -concurrently with future calls from the client (unless the server threadpool has -only one thread).</p> - -<p>In addition to synchronous callbacks, <code>oneway</code> calls from a -single-threaded client may be handled concurrently by a server with multiple -threads in its threadpool, but only if those <code>oneway</code> calls are -executed on different interfaces. <code>oneway</code> calls on the same -interface are always serialized.</p> - -<p class=note><strong>Note:</strong> We strongly encourage server functions to -return as soon as they have called the callback function.</p> - -<p>For example (in C++):</p> - -<pre class="prettyprint"> -Return<void> someMethod(someMethod_cb _cb) { - // Do some processing, then call callback with return data - hidl_vec<uint32_t> vec = ... - _cb(vec); - // At this point, the client's callback will be called, - // and the client will resume execution. - ... - return Void(); // is basically a no-op -}; -</pre> - -<h2 id=client>Client threading model</h2> -<p>The threading model on the client differs between non-blocking calls -(functions that are marked with the <code>oneway</code> keyword) and blocking -calls (functions that do not have the <code>oneway</code> keyword specified).</p> - -<h3 id=block>Blocking calls</h3> -<p>For blocking calls, the client blocks until one of the following happens:</p> - -<ul> -<li>Transport error occurs; the <code>Return</code> object contains an error -state that can be retrieved with <code>Return::isOk()</code>.</li> -<li>Server implementation calls the callback (if there was one).</li> -<li>Server implementation returns a value (if there was no callback parameter). -</li> -</ul> - -<p>In case of success, the callback function the client passes as an argument is -always called by the server before the function itself returns. The callback is -executed on the same thread that the function call is made on, so implementers -must be careful with holding locks during function calls (and avoid them -altogether when possible). A function without a <code>generates</code> statement -or a <code>oneway</code> keyword is still blocking; the client blocks until the -server returns a <code>Return<void></code> object.</p> - -<h3 id=oneway>Oneway calls</h3> -<p>When a function is marked <code>oneway</code>, the client returns immediately -and does not wait for the server to complete its function call invocation. At the -surface (and in aggregate), this means the function call takes half the -time because it is executing half the code, but when writing implementations that -are performance sensitive, this has some scheduling implications. Normally, -using a oneway call causes the caller to continue to be scheduled whereas -using a normal synchronous call causes the scheduler to immediately transfer -from the caller to the callee process. This is a performance optimization in -binder. For services where the oneway call must be executed in the target process -with a high priority, the scheduling policy of the receiving service can be -changed. In C++, using <code>libhidltransport</code>'s method -<code>setMinSchedulerPolicy</code> with the scheduler priorities and policies -defined in <code>sched.h</code> ensures that all calls into the service run at -least at the set scheduling policy and priority.</p> - - </body> -</html> |