Skip to content

AsyncTask

Defined in asynctask@1.1.1

This module provides a way to run tasks asynchronously.

Importing this module automatically enables --threaded flag of the compiler. Note that this causes some overhead even for a single-threaded program.

Values

namespace AsyncTask

get

Type: AsyncTask::Task a -> a

Gets the result of a task.

This function blocks the current thread until the task is finished.

make

Type: (() -> a) -> AsyncTask::Task a

Makes a task which performs a computation asynchronously.

Example:

module Main;
import AsyncTask;

main : IO ();
main = (
    let sum_range = |from, to| (
        loop((0, from), |(sum, i)| (
            if i == to { break $ sum };
            continue $ (sum + i, i + 1)
        ))
    );
    let n = 1000000000;
    // Compute the sum of numbers from 0 to n/2 - 1.
    // This task will be executed asynchronously (if you are using multi-core CPU).
    let sum_former = AsyncTask::make(|_| sum_range(0, n/2));
    // Compute the sum of numbers from n/2 to n.
    // We perfom this in the current thread while waiting for the result of the former task.
    let sum_latter = sum_range(n/2, n);
    // Sum up the results of the two computations.
    let sum = sum_former.get + sum_latter;
    // Then the sum should be n * (n - 1) / 2.
    assert_eq(|_|"", sum, n * (n - 1) / 2);;
    println $
        "Sum of numbers from 0 to " + (n - 1).to_string +
        " is " + sum_former.get.to_string + " + " + sum_latter.to_string +
        " = " + sum.to_string + "."
);

number_of_processors

Type: Std::I64

Gets the number of processors (CPU cores) currently available. This is implemented by calling sysconf(_SC_NPROCESSORS_ONLN). The runtime pools as many threads as this number to execute asynchronous tasks.

namespace AsyncTask::AsyncIOTask

get

Type: AsyncTask::AsyncIOTask::IOTask a -> Std::IO a

Get the result of an asynchronous I/O action.

make

Type: Std::IO a -> Std::IO (AsyncTask::AsyncIOTask::IOTask a)

An IO version of AsyncTask::make.

Example:

module Main;
import AsyncTask;

main : IO ();
main = (
    let print_ten : I64 -> IO () = |task_num| (
        loop_m(0, |i| (
            if i == 10 {
                break_m $ ()
            } else {
                let msg = "task number: " + task_num.to_string + ", i: " + i.to_string;
                msg.println;;
                continue_m $ i + 1
            }
        ))
    );
    (*AsyncIOTask::make(print_ten(0))).get;;
    (*AsyncIOTask::make(print_ten(1))).get;;
    pure()
);

namespace AsyncTask::Var

get

Type: AsyncTask::Var::Var a -> Std::IO a

Get a value stored in a Var.

lock

Type: (a -> Std::IO b) -> AsyncTask::Var::Var a -> Std::IO b

var.lock(act) performs an action on the value in var while locking var to prevent it from being changed by another thread.

make

Type: a -> Std::IO (AsyncTask::Var::Var a)

Create a new Var object.

mod

Type: (a -> a) -> AsyncTask::Var::Var a -> Std::IO ()

Atomically modifies a value in a Var.

set

Type: a -> AsyncTask::Var::Var a -> Std::IO ()

Set a value to a Var.

wait

Type: (a -> Std::Bool) -> AsyncTask::Var::Var a -> Std::IO ()

var.wait(cond) waits until cond on the value of var is satisfied.

Note that it is not assured that cond is satisfied after wait returned; the value in var may be changed after cond is evaluated.

wait_and_lock

Type: (a -> Std::Bool) -> (a -> Std::IO b) -> AsyncTask::Var::Var a -> Std::IO b

var.wait_and_lock(cond, act) waits until cond on the value of var is satisfied, then performs act on the value in var while locking var to prevent it from being changed by another thread.

Types and aliases

namespace AsyncTask

Task

Defined as: type Task a = unbox struct { ...fields... }

A type for a computation task that runs asynchronously.

field dtor

Type: Std::FFI::Destructor AsyncTask::TaskHandle

TaskHandle

Defined as: type TaskHandle = Std::Ptr

A native handle of a task. This type is used only for implementation.

namespace AsyncTask::AsyncIOTask

IOTask

Defined as: type IOTask a = unbox struct { ...fields... }

A type for an I/O action that can be run asynchronously.

field _task

Type: AsyncTask::Task (Std::IO::IOState, a)

namespace AsyncTask::Var

Var

Defined as: type Var a = unbox struct { ...fields... }

A type of variable which can be modified from multiple threads.

module Main;
import AsyncTask;

main : IO ();
main = (
    let logger = *Var::make([]); // A mutable array of strings.

    // Launch multiple threads, and log in which order each thread is executed.
    let num_threads = number_of_processors * 2;
    Iterator::range(0, num_threads).fold_m((), |i, _| (
        AsyncIOTask::make(
            logger.lock(|logs| (
                let count = logs.get_size;
                let msg = "Thread " + i.to_string + " is running at " + count.to_string +
                    if count % 10 == 1 { "st" } else if count % 10 == 2 { "nd" } else if count % 10 == 3 { "rd" } else { "th" };
                let msg = msg + if i == count { "." } else { "!" };
                logger.set(logs.push_back(msg))
            ))
        )
    ));;

    // Wait until all threads are finished.
    +logger.wait(|logs| logs.get_size == num_threads);

    println $ (*logger.get).to_iter.join("\n")
);
field _dtor

Type: Std::FFI::Destructor AsyncTask::Var::VarHandle

VarHandle

Defined as: type VarHandle = Std::Ptr

VarValue

Defined as: type VarValue a = box struct { ...fields... }

field value

Type: a

Traits and aliases

Trait implementations