Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document @threadcall #17915

Merged
merged 1 commit into from
Aug 9, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion base/docs/helpdb/Base.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4839,7 +4839,7 @@ IntSet
"""
Task(func)

Create a `Task` (i.e. thread, or coroutine) to execute the given function (which must be
Create a `Task` (i.e. coroutine) to execute the given function (which must be
callable with no arguments). The task exits when this function returns.
"""
Task
Expand Down
25 changes: 25 additions & 0 deletions doc/manual/parallel-computing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1076,6 +1076,31 @@ The iteration space is split amongst the threads, after which each thread writes

Note that :obj:`Threads.@threads` does not have an optional reduction parameter like :obj:`@parallel`.

@threadcall (Experimental)
--------------------------
All I/O tasks, timers, REPL commands, etc are multiplexed onto a single OS thread via an event loop.
A patched version of libuv (http://docs.libuv.org/en/v1.x/) provides this functionality. Yield points provide
for co-operatively scheduling multiple tasks onto the same OS thread. I/O tasks and timers yield implicitly while
waiting for the event to occur. Calling `yield()` explicitly allows for other tasks to be scheduled.

Thus, a task executing a ``ccall`` effectively prevents the Julia scheduler from executing any other
tasks till the call returns. This is true for all calls into external libraries. Exceptions are calls into
custom C code that call back into Julia (which may then yield) or C code that calls ``jl_yield()``(C equivalent of ``yield()``).

Note that while Julia code runs on a single thread (by default), libraries used by Julia may launch their own internal
threads. For example, the BLAS library may start as many threads as there are cores on a machine.

The ``@threadcall`` macro addresses scenarios where we do not want a ``ccall`` to block the main Julia event loop.
It schedules a C function for execution in a separate thread. A threadpool with a default size of 4 is used for this.
The size of the threadpool is controlled via environment variable UV_THREADPOOL_SIZE. While waiting for a free thread,
and during function execution once a thread is available, the requesting task (on the main Julia event loop)
yields to other tasks. Note that ``@threadcall`` does not return till the execution is complete. From a user point of
view, it is therefore a blocking call like other Julia API.

It is very important that the called function does not call back into Julia.

``@threadcall`` may be removed/changed in future versions of Julia.

.. rubric:: Footnotes

.. [#mpi2rma] In this context, MPI refers to the MPI-1 standard. Beginning with MPI-2, the MPI standards committee introduced a new set of communication mechanisms, collectively referred to as Remote Memory Access (RMA). The motivation for adding RMA to the MPI standard was to facilitate one-sided communication patterns. For additional information on the latest MPI standard, see http://www.mpi-forum.org/docs.
Expand Down
13 changes: 12 additions & 1 deletion doc/stdlib/parallel.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Tasks

.. Docstring generated from Julia source

Create a ``Task`` (i.e. thread, or coroutine) to execute the given function (which must be callable with no arguments). The task exits when this function returns.
Create a ``Task`` (i.e. coroutine) to execute the given function (which must be callable with no arguments). The task exits when this function returns.

.. function:: yieldto(task, arg = nothing)

Expand Down Expand Up @@ -814,6 +814,17 @@ will) change in the future.

For further details, see LLVM's ``fence`` instruction.

ccall using a threadpool (Experimental)
---------------------------------------

.. function:: @threadcall((cfunc, clib), rettype, (argtypes...), argvals...)

.. Docstring generated from Julia source

The ``@threadcall`` macro is called in the same way as ``ccall`` but does the work in a different thread. This is useful when you want to call a blocking C function without causing the main ``julia`` thread to become blocked. Concurrency is limited by size of the libuv thread pool, which defaults to 4 threads but can be increased by setting the ``UV_THREADPOOL_SIZE`` environment variable and restarting the ``julia`` process.

Note that the called function should never call back into Julia.

Synchronization Primitives
--------------------------

Expand Down