Next: , Previous: thread.future, Up: Top   [Contents]


107 thread

%--------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et
%--------------------------------------------------%
% Copyright (C) 2000-2001, 2003-2004, 2006-2008, 2010-2011 The University
% of Melbourne.
% Copyright (C) 2014-2024 The Mercury team.
% This file is distributed under the terms specified in COPYING.LIB.
%--------------------------------------------------%
%
% File: thread.m.
% Authors: conway, wangp.
% Stability: medium.
%
% This module defines the Mercury concurrency interface.
%
% The term `concurrency' refers to threads, not necessarily to parallel
% execution of those threads. (The latter is also possible if you are using
% one of the .par grades or the Java or C# backends.)
%
%--------------------------------------------------%
%--------------------------------------------------%

:- module thread.
:- interface.

:- import_module io.
:- import_module maybe.

:- include_module barrier.
:- include_module channel.
:- include_module closeable_channel.
:- include_module future.
:- include_module mvar.
:- include_module semaphore.

%--------------------------------------------------%

    % Abstract type representing a detached thread.
    %
:- type thread.

    % Abstract type representing a joinable thread.
    %
:- type joinable_thread(T).

    % can_spawn succeeds if spawn/4 is supported in the current grade.
    %
:- pred can_spawn is semidet.

    % can_spawn_native succeeds if spawn_native/4 is supported in the current
    % grade.
    %
:- pred can_spawn_native is semidet.

    % spawn(Closure, IO0, IO) is true iff IO0 denotes a list of I/O
    % transactions that is an interleaving of those performed by Closure
    % and those contained in IO - the list of transactions performed by
    % the continuation of spawn/3.
    %
    % Operationally, spawn/3 is like spawn/4 except that Closure does not
    % accept a thread handle argument, and an exception is thrown if the
    % thread cannot be created.
    %
:- pred spawn(pred(io, io)::in(pred(di, uo) is cc_multi),
    io::di, io::uo) is cc_multi.

    % spawn(Closure, Res, IO0, IO) creates a new thread and performs Closure in
    % that thread. On success it returns ok(Thread) where Thread is a handle to
    % the new thread. Otherwise it returns an error.
    %
:- pred spawn(pred(thread, io, io)::in(pred(in, di, uo) is cc_multi),
    maybe_error(thread)::out, io::di, io::uo) is cc_multi.

    % A type representing options that affect thread creation.
    %
:- type thread_options.

    % Create a new thread options object with options set to their default
    % values. The options are:
    %
    % - min_stack_size: the minimum stack size in bytes (default: 0).
    %   The special value 0 means to use the default stack size as chosen by
    %   the underlying environment.
    %
:- func init_thread_options = thread_options.

    % Set the minimum stack size (in bytes) for a new thread created with these
    % thread options. This only affects C grades that use POSIX threads.
    % The Java and C# backends do not yet respect the minimum stack size
    % option.
    %
:- pred set_min_stack_size(uint::in, thread_options::in, thread_options::out)
    is det.

    % spawn_native(Closure, Res, !IO):
    % Same as spawn_native(Closure, init_thread_options, Res, !IO).
    %
:- pred spawn_native(pred(thread, io, io)::in(pred(in, di, uo) is cc_multi),
    maybe_error(thread)::out, io::di, io::uo) is cc_multi.

    % spawn_native(Closure, Options, Res, IO0, IO):
    % Like spawn/4, but Closure will be performed in a separate "native thread"
    % of the environment the program is running in (POSIX thread, Windows
    % thread, Java thread, etc.).
    %
    % spawn_native exposes a low-level implementation detail, so it is more
    % likely to change with the implementation.
    %
    % Rationale: on the low-level C backend Mercury threads are multiplexed
    % onto a limited number of OS threads. A call to a blocking procedure
    % prevents that OS thread from making progress on another Mercury thread.
    % Also, some foreign code depends on OS thread-local state so needs to be
    % consistently executed on a dedicated OS thread to be usable.
    %
:- pred spawn_native(pred(thread, io, io)::in(pred(in, di, uo) is cc_multi),
    thread_options::in, maybe_error(thread)::out, io::di, io::uo) is cc_multi.

    % spawn_native_joinable(Closure, Options, Res, IO0, IO);
    %
    % Create a joinable native thread (like spawn_native), then perform Closure
    % in that thread. Another thread can call join_thread/4 to wait for the
    % thread to terminate, and fetch the output returned by Closure.
    % The thread will continue to take up system resources until it terminates
    % and has been joined by a call to join_thread/4.
    %
:- pred spawn_native_joinable(
    pred(joinable_thread(T), T, io, io)::in(pred(in, out, di, uo) is cc_multi),
    thread_options::in, maybe_error(joinable_thread(T))::out, io::di, io::uo)
    is cc_multi.

    % join_thread(Thread, Res, !IO):
    %
    % Wait for the specified thread to terminate. If the thread has already
    % terminated, join_thread/4 will return immediately. On success, Res will
    % be ok(Output) where Output is the value returned by the closure
    % performed on that thread.
    %
    % A thread must only be joined once. If multiple threads simultaneously
    % try to join with the same thread, the results are undefined.
    %
:- pred join_thread(joinable_thread(T)::in, maybe_error(T)::out,
    io::di, io::uo) is cc_multi.

    % yield(IO0, IO) is logically equivalent to (IO = IO0) but
    % operationally, yields the Mercury engine to some other thread
    % if one exists.
    %
    % NOTE: this is not yet implemented in the hl*.par.gc grades; currently
    % it is a no-op in those grades.
    %
:- pred yield(io::di, io::uo) is det.

    % num_processors(Num, !IO)
    %
    % Retrieve the number of processors available to this process for
    % parallel execution, if known.
    %
    % Note that the number of available processors can be different from the
    % actual number of processors/cores:
    %
    %  + It includes hardware threads.
    %  + The Mercury grade may restrict the process to one processor.
    %  + The OS may be configured to restrict the number of processors
    %    available (e.g. cpuset(7) on Linux).
    %
:- pred num_processors(maybe(int)::out, io::di, io::uo) is det.

%--------------------------------------------------%
%--------------------------------------------------%


Next: , Previous: thread.future, Up: Top   [Contents]