Eager Future

Introduction

Eager Future is a Common Lisp library for concurrent programming with composable, eager futures (look here for a thorough discussion of what exactly that means).

Eager Future is a rewrite of Marijn Haverbeke's PCall library. The main differences between Eager Future and PCall are:

Eager Future is built on the assumption that multi-core chips will provide a friendly habitat for speculative execution and many live threads.

Download

The latest version of Eager Future is 0.4. Older versions can be downloaded from the release directory.

Eager Future is available via ASDF-Install: (asdf-install:install :eager-future)

Repository

The Eager Future repository can be checked out with darcs:

darcs get http://common-lisp.net/project/eager-future/repository/eager-future/

Support and mailing list

Questions should be directed to the eager-future-devel mailing list.

Documentation

API

function PCALL function
→ future
Begins asynchronous execution the given function of no arguments, returning an object of type FUTURE that can later be used to retrieve the result of executing the function. Note that the execution of the function takes places in an unspecified dynamic environment.

macro PEXEC (&body body)
→ future
A shorthand for (pcall (lambda () ...)).

macro PLET ((bindings) &body body)
Like LET, but all bindings are evaluated asynchronously.

function YIELD future
→ values
Given an object of type FUTURE, returns the value(s) that resulted from executing the function associated with that future. If execution has not yet finished, blocks until it has. If a condition was raised during execution, YIELD will raise a condition of type EXECUTION-ERROR that wraps the original condition (which can be examined by calling EXECUTION-ERROR-CAUSE on the EXECUTION-ERROR).

function READY-TO-YIELD? future
→ boolean
Returns T if the future can YIELD without blocking, NIL otherwise.

function SELECT (&rest futures)
→ future
Returns the first of the given futures that can YIELD without blocking.

special variable *THREAD-POOL*
Controls which thread pool PCALLed futures are run in. An instance of THREAD-POOL by default. Each thread pool class has a THREAD-LIMIT slot, which has class-specific behavior.

class THREAD-POOL
Eager execution thread pool with a soft thread count limit. When the THREAD-LIMIT is nil (the default), any newly spawned threads are never released from the thread pool. When an integer, indicates the desired size of the thread pool - any idle threads above this limit are freed.

class FIXED-FIFO-THREAD-POOL
Fixed-sized thread pool. Any tasks that cannot be immediately accomodated by the pool are placed in a queue. Note that this makes FIXED-FIFO-THREAD-POOL inappropriate for use when composing timing-sensitive futures with SELECT. When THREAD-LIMIT is nil (the default), the size of the thread pool is unbounded. Otherwise it must be an integer indicating the maximum size of the pool.

Examples

(defun do-something (with-timeout)
  (yield (select (pcall #'heavy-io-or-compute-bound-function)
                 (pexec (sleep with-timeout) :timed-out))))

The above function DO-SOMETHING illustrates how futures can be composed to provide soft real-time bounds for asynchronous computations.

Project members

Eager Future is maintained by Vladimir Sedach.

License

Eager Future is licensed under the terms of the zlib license. Details are contained in the LICENSE file, included with the distribution.