10 MLton extensions
10.1 #line directives
To aid in the debugging of code produced by program genenerators such as
Noweb,
MLton supports comments with #line directives of the form (*#line line.col "file"*). Here,
line and col are sequences of decimal digits and file is the source file. A #line directive causes the front end
to believe that the character following the right parenthesis is at
the line and column of the specified file. A #line directive only
affects the reporting of error messages and does not affect program
semantics (except for functions like MLton.Exn.history which
report source file positions). Syntactically invalid #line
directives are ignored. To prevent incompatibilites with SML, the
file name may not contain the character sequence *).
10.2 The MLton structure
The remainder of this section describes the modules MLton makes
available that are not part of the Standard ML Basis Library. As a
warning, please keep in mind that the MLton structure and its
substructures do change from release to release of MLton.
structure MLton:
sig
val eq: 'a * 'a -> bool
val isMLton: bool
val share: 'a -> unit
val shareAll: unit -> unit
val size: 'a -> int
structure Array: MLTON_ARRAY
structure BinIO: MLTON_BIN_IO
structure Cont: MLTON_CONT
structure Exn: MLTON_EXN
structure Finalizable: MLTON_FINALIZABLE
structure GC: MLTON_GC
structure IntInf: MLTON_INT_INF
structure Itimer: MLTON_ITIMER
structure Platform: MLTON_PLATFORM
structure Pointer: MLTON_POINTER
structure ProcEnv: MLTON_PROC_ENV
structure Process: MLTON_PROCESS
structure Profile: MLTON_PROFILE
structure Random: MLTON_RANDOM
structure Rlimit: MLTON_RLIMIT
structure Rusage: MLTON_RUSAGE
structure Signal: MLTON_SIGNAL
structure Socket: MLTON_SOCKET
structure Syslog: MLTON_SYSLOG
structure TextIO: MLTON_TEXT_IO
structure Thread: MLTON_THREAD
structure Vector: MLTON_VECTOR
structure Weak: MLTON_WEAK
structure Word: MLTON_WORD where type word = Word.word
structure Word8: MLTON_WORD where type word = Word8.word
structure World: MLTON_WORLD
end
- eq (x, y)
-
returns true if x and y are equal as pointers. For simple
types like char, int, and word, this is the same as
equals. For arrays, datatypes, strings, tuples, and vectors, this is
a simple pointer equality. The semantics is a bit murky.
- isMLton
-
is always true in a MLton implementation, and is always false in a
stub implementation.
- share x
-
maximizes sharing in the heap for the object graph reachable from x.
- shareAll ()
-
maximizes sharing in the heap by sharing space for equivalent
immutable objects. A call to shareAll performs a major garbage
collection, and takes time proportional to the size of the heap.
- size x
-
return the amount of heap space (in bytes) taken by the value of x, including all objects reachable from x by following
pointers. It takes time proportional to the size of x. For an
example, see examples/size.sml.
signature MLTON_ARRAY =
sig
val unfoldi: int * 'b * (int * 'b -> 'a * 'b) -> 'a array
end
- unfoldi (n, b, f)
-
construct an array a of a length n, whose elements ai are determined
by the equations b0 = b and (ai, bi+1) = f (i, bi).
signature MLTON_BIN_IO =
MLTON_IO
where type instream = BinIO.instream
where type outstream = BinIO.outstream
See Section 10.2.9.
signature MLTON_CONT =
sig
type 'a t
val callcc: ('a t -> 'a) -> 'a
val prepend: 'a t * ('b -> 'a) -> 'b t
val throw: 'a t * 'a -> 'b
val throw': 'a t * (unit -> 'a) -> 'b
end
- type 'a t
-
the type of continuations that expect a value of type 'a.
- callcc f
-
apply f to the current continuation. Because this copies the
entire stack, callcc takes time proportional to the current
stack size.
- prepend (k, f)
-
compose a function f with a continuation k to create a
continuation that first does f and then does k. This
is a constant time operation.
- throw (k, v)
-
throw value v to continuation k. Because this copies the
entire stack of k, throw takes time proportional to the
size of this stack.
- throw' (k, th)
-
a generalization of throw that evaluates th () in the context
of k. Thus, for example, if th () raises an exception or
grabs another continuation, it will see k, not the current
continuation.
signature MLTON_EXN =
sig
val addExnMessager: (exn -> string option) -> unit
val history: exn -> string list
val topLevelHandler: exn -> 'a
end
- addExnMessager f
-
adds f as a pretty-printer to be used by General.exnMessage for converting exceptions to strings. Messagers
are tried in order from most recently added to least recently added.
- history e
-
returns the file positions that have raised the exception e, in reverse
chronological order. A handle expression that implicitly reraises counts
as a raise. history will return [] unless the program is compiled
with -exn-history true.
- topLevelHandler e
-
behave as if the top level handler received the exception e,
that is, print out the unhandled exception message for e and
exit.
10.2.6 MLton.Finalizable
signature MLTON_FINALIZABLE =
sig
type 'a t
val addFinalizer: 'a t * ('a -> unit) -> unit
val finalizeBefore: 'a t * 'b t -> unit
val new: 'a -> 'a t
val touch: 'a t -> unit
val withValue: 'a t * ('a -> 'b) -> 'b
end
A finalizable value is a value to which finalizers can be
attached. A finalizer is a function that runs after a garbage
collection determines that the value to which it is attached is
unreachable. Reachability is the same as with weak pointers (see
Section 10.2.25). The finalizer is treated like a signal handler, in
that it runs asynchronously in a separate thread, with signals
blocked, and will not run within a critical section (see
Section 10.2.23).
For an example, see the examples/finalizable directory.
- addFinalizer (v, f)
-
adds f as a finalizer to v. This means that sometime
after the last call to withValue on v completes and v becomes unreachable, f will be called with the value of v.
- finalizeBefore (v1, v2)
-
ensures that v1 will be finalized before v2. A cycle of
values v = v1, ..., vn = v with finalizeBefore (vi, vi+1) will result in none of the vi being
finalized.
- new x
-
creates a new finalizable value, v, with value x. The
finalizers of v will run sometime after the last call to withValue on v when the garbage collector determines that v is unreachable.
- touch v
-
ensures that v's finalizers will not run before the call to
touch.
- withValue (v, f)
-
returns the result of applying f to the value of v and
ensures that v's finalizers will not run before f
completes. The call to f is a nontail call.
signature MLTON_GC =
sig
val collect: unit -> unit
val pack: unit -> unit
val setMessages: bool -> unit
val setSummary: bool -> unit
val unpack: unit -> unit
end
-
collect ()
-
causes a garbage collection to occur.
- pack ()
-
shrinks the heap as much as possible so that other processes can use
available RAM.
- setMessages b
-
controls whether diagnostic messages are printed at the beginning and
end of each garbage collection. It is the same as the gc-messages runtime system option.
- setSummary b
-
controls whether a summary of garbage collection statistics is printed
upon termination of the program. It is the same as the gc-summary runtime system option.
- unpack ()
-
resizes a packed heap to the size desired by the runtime.
10.2.8 MLton.IntInf
signature MLTON_INT_INF =
sig
type t
val areSmall: t * t -> bool
val gcd: t * t -> t
val isSmall: t -> bool
datatype rep =
Big of word vector
| Small of int
val rep: t -> rep
end
MLton represents an arbitrary precision integer either as an
unboxed 32 bit word with the bottom bit set to 1 and the top 31 bits
representing a small integer in [-230, 230), or as a pointer
to a vector of words where the first word indicates the sign and the
rest are the limbs of GNUmp big integer.
- type t
-
the same as type IntInf.int.
- areSmall (a, b)
-
returns true iff both a and b are small.
- gcd (a, b)
-
use the GNUmp's fast gcd implementation.
- isSmall a
-
returns true iff a is small.
- datatype rep
-
the underlying representation of an IntInf.
- rep i
-
return the underlying representation of i.
signature MLTON_IO =
sig
type instream
type outstream
val inFd: instream -> Posix.IO.file_desc
val mkstemp: string -> string * outstream
val mkstemps: {prefix: string, suffix: string} -> string * outstream
val newIn: Posix.IO.file_desc * string -> instream
val newOut: Posix.IO.file_desc * string -> outstream
val outFd: outstream -> Posix.IO.file_desc
end
- inFd ins
-
return the file descriptor corresponding to ins.
- mkstemp s
-
like the C mkstemp function, generate and open a tempory file with prefix
s.
- mkstemps {prefix, suffix}
-
mkstemps is like mkstemp, except it has both a prefix and suffix.
- newIn (fd, name)
-
create a new instream from file descriptor
fd, with name used in any Io exceptions later
raised.
- newOut (fd, name)
-
create a new outstream from file descriptor
fd, with name used in any Io exceptions later
raised.
- outFd out
-
return the file descriptor corresponding to
out.
signature MLTON_ITIMER =
sig
datatype t =
Prof
| Real
| Virtual
val set: t * {interval: Time.time, value: Time.time} -> unit
val signal: t -> Posix.Signal.signal
end
-
set (t, {interval, value})
-
set the interval timer (using setitimer) specified by t to
the given interval and value.
- signal t
-
return the signal corresponding to t.
10.2.11 MLton.Platform
signature MLTON_PLATFORM =
sig
structure Arch:
sig
datatype t = PowerPC | Sparc | X86
val fromString: string -> t option
val host: t
val toString: t -> string
end
structure OS:
sig
datatype t = Cygwin | Darwin | FreeBSD | Linux | MinGW
| NetBSD | OpenBSD | Solaris
val fromString: string -> t option
val host: t
val toString: t -> string
end
end
- datatype Arch.t
-
the architectures to which MLton can compile.
- Arch.fromString a
-
convert from string to architecture. Case insensitive.
- Arch.host
-
the architecture for which the program is compiled.
- Arch.toString
-
string for architecture.
- datatype OS.t
-
the operating systems to which MLton can compile.
- OS.fromString
-
convert from string to operating system. Case insensitive.
- OS.host
-
the operating system for which the program is compiled.
- OS.toString
-
string for operating system.
signature MLTON_POINTER =
sig
eqtype t
val add: t * word -> t
val compare: t * t -> order
val diff: t * t -> word
val getInt8: t * int -> Int8.int
val getInt16: t * int -> Int16.int
val getInt32: t * int -> Int32.int
val getInt64: t * int -> Int64.int
val getPointer: t * int -> t
val getReal32: t * int -> Real32.real
val getReal64: t * int -> Real64.real
val getWord8: t * int -> Word8.word
val getWord16: t * int -> Word16.word
val getWord32: t * int -> Word32.word
val getWord64: t * int -> Word64.word
val null: t
val setInt8: t * int * Int8.int -> unit
val setInt16: t * int * Int16.int -> unit
val setInt32: t * int * Int32.int -> unit
val setInt64: t * int * Int64.int -> unit
val setPointer: t * int * t -> unit
val setReal32: t * int * Real32.real -> unit
val setReal64: t * int * Real64.real -> unit
val setWord8: t * int * Word8.word -> unit
val setWord16: t * int * Word16.word -> unit
val setWord32: t * int * Word32.word -> unit
val setWord64: t * int * Word64.word -> unit
val sub: t * word -> t
end
-
eqtype t
-
The type of pointers, i.e. machine addresses.
- add (p, w)
-
returns the pointer w bytes after than p. Does not check
for overflow.
- compare (p1, p2)
-
compare the pointer p1 to the pointer p2 (as addresses).
- diff (p1, p2)
-
returns the number of bytes w such that add (p2, w) = p1.
Does not check for overflow.
- getX (p, i)
-
returns the object stored at index i of the array of X objects
pointed to by p. For example, getWord32 (p, 7) returns
the 32-bit word stored 28 bytes beyond p.
- null
-
the null pointer, i.e. 0.
- setX (p, i, v)
-
assigns v to the object stored at index i of the array of X objects pointed to by p. For example, setWord32 (p, 7,
w) stores the 32-bit word w at the address 28 bytes beyond p.
- sub (p, w)
-
returns the pointer w bytes before p. Does not check for
overflow.
signature MLTON_PROC_ENV =
sig
val setenv: {name: string, value: string} -> unit
end
-
setenv {name, value}
-
Like the C setenv function. Does not require name or value to be null terminated.
signature MLTON_PROCESS =
sig
type pid = Posix.Process.pid
val spawn: {path: string, args: string list} -> pid
val spawne: {path: string, args: string list, env: string list} -> pid
val spawnp: {file: string, args: string list} -> pid
end
The spawn functions provide an alternative to the fork/exec idiom that is typically used to create a new process.
On most platforms, the spawn functions are simple wrappers
around fork/exec. However, on Cygwin, the spawn
functions are primitive and are both faster and more reliable than
fork/exec. All spawn functions return the process
id of the spawned process. They differ in how the executable is found
and the environment that it uses.
-
spawn {path, args}
-
Start a new process running the executable specified by path with the
arguments args. Like Posix.Process.exec.
- spawne {path, args, env}
-
Start a new process running the executable specified by path with the
arguments args and environment env. Like Posix.Process.exece.
- spawnp {file, args}
-
Search the PATH environment variable for an executable named file,
and start a new process running that executable with the arguments args.
Like Posix.Process.execp.
signature MLTON_PROFILE =
sig
structure Data:
sig
type t
val equals: t * t -> bool
val free: t -> unit
val malloc: unit -> t
val write: t * string -> unit
end
val isOn: bool
val withData: Data.t * (unit -> 'a) -> 'a
end
MLton.Profile provides profiling control from within the
program. For more on profiling, see Section 7. In order to
most efficiently execute non-profiled programs, when compiling -profile no (the default), type Data.t is equivalent to unit ref.
- isOn
-
a compile-time constant that is true when compiling -profile
time or -profile alloc.
- type Data.t
-
the type of a unit of profiling data.
- Data.equals (x, y)
-
returns true if the x and y are the same unit of profiling
data.
- Data.free x
-
frees the memory associated with the unit of profiling data x.
It is an error to free the current unit of profiling data or to free a
previously freed unit of profiling data. When compiling -profile
no, Data.free x is a no-op.
- Data.malloc ()
-
returns a new unit of profiling data. Each unit of profiling data is
allocated from the process heap (not the MLton heap) and
consumes memory proportional to the number of source functions. When
compiling -profile no, Data.malloc () is equivalent to
allocating a new unit ref.
- write (x, f)
-
writes the accumulated ticks in the unit of profiling data x to
file f. It is an error to write a previously freed unit of
profiling data. When compiling -profile no, write (x, f)
is a no-op. A program compiled with -profile time or -profile alloc will always write the current unit of profiling data
at program exit to a file named mlmon.out.
- withData (d, f)
-
runs f with d as the unit of profiling data, and returns
the result of f after restoring the current unit of profiling
data. When compiling -profile no, withData (d, f) is
equivalent to f ().
signature MLTON_RANDOM =
sig
val alphaNumChar: unit -> char
val alphaNumString: int -> string
val rand: unit -> word
val seed: unit -> word option
val srand: word -> unit
val useed: unit -> word option
end
-
alphaNumChar ()
-
returns a random alphanumeric character.
- alphaNumString n
-
return a string of length n of random alphanumeric characters.
- rand ()
-
return the next pseudrandom number.
- seed ()
-
return a random word from /dev/random. Useful as an arg to srand. If /dev/random can not be read from, seed ()
returns NONE. A call to seed may block until enough
random bits are available.
- srand w
-
set the seed used by rand to w.
- useed ()
-
return a random word from /dev/urandom. Useful as an arg to
srand. If /dev/urandom can not be read from, useed
() returns NONE. A call to useed will never block -- it
will instead return lower quality random bits.
signature MLTON_RLIMIT =
sig
type rlim = word
val infinity: rlim
type t
val coreFileSize: t (* CORE max core file size *)
val cpuTime: t (* CPU CPU time in seconds *)
val dataSize: t (* DATA max data size *)
val fileSize: t (* FSIZE Maximum filesize *)
val lockedInMemorySize: t (* MEMLOCK max locked address space *)
val numFiles: t (* NOFILE max number of open files *)
val numProcesses: t (* NPROC max number of processes *)
val residentSetSize: t (* RSS max resident set size *)
val stackSize: t (* STACK max stack size *)
val virtualMemorySize: t (* AS virtual memory limit *)
val get: t -> {hard: rlim, soft: rlim}
val set: t * {hard: rlim, soft: rlim} -> unit
end
MLton.Rlimit provides a wrapper around the C getrlimit and
setrlimit functions.
-
type rlim
-
the type of resource limits.
- infinity
-
indicates that a resource is unlimited.
- type t
-
the types of resources that can be inspected and modified.
- get r
-
returns the current hard and soft limits for resource r. May
raise OS.SysErr.
- set (r, {hard, soft})
-
sets the hard and soft limits for resource r. May raise OS.SysErr.
signature MLTON_RUSAGE =
sig
type t = {utime: Time.time, (* user time *)
stime: Time.time} (* system time *)
val rusage: unit -> {children: t,
gc: t,
self: t}
end
-
type t
-
corresponds to a subset of the C struct rusage.
- rusage ()
-
corresponds to the C getrusage function. It returns the
resource usage of the exited children, the garbage collector, and the
process itself. The process time (self) includes the gc time.
signature MLTON_SIGNAL =
sig
type t
type signal = t
structure Handler:
sig
type t
val default: t
val handler: (Thread.Runnable.t -> Thread.Runnable.t) -> t
val ignore: t
val isDefault: t -> bool
val isIgnore: t -> bool
val simple: (unit -> unit) -> t
end
structure Mask:
sig
type t
val all: t
val allBut: signal list -> t
val block: t -> unit
val getBlocked: unit -> t
val isMember: t * signal -> bool
val none: t
val setBlocked: t -> unit
val some: signal list -> t
val unblock: t -> unit
end
val getHandler: t -> Handler.t
val handled: unit -> Mask.t
val prof: t
val restart: bool ref
val setHandler: t * Handler.t -> unit
val suspend: Mask.t -> unit
val vtalrm: t
end
Signals handlers are functions from (runnable) threads to (runnable)
threads. When a signal handler is invoked, it receives as an argument
the thread that was interrupted by the signal. The signal handler
returns the thread that it would like to resume execution (this is
often the thread that it was passed). It is an error for a signal
handler to raise an unhandled exception.
A signal handler is never invoked while the running thread is in a
critical section (see Section 10.2.23). Invoking a signal handler
implicitly enters a critical section and the normal return of a signal
handler implicitly exits the critical section; hence, a signal handler
is never interrupted by another signal handler.
Signal handling interacts in a non-trivial way with those functions in
the Basis Library that correspond directly to interruptable system
calls (a subset of those functions that may raise OS.SysError).
The desire is that these functions should have predictable semantics.
The principal concerns are:
-
system calls that are interrupted by signals should, by default, be
restarted; the alternative is to raise OS.SysError(Posix.Error.errorMsg Posix.Error.intr, SOME
Posix.Error.intr). This behavior is determined dynamically by
the value of Signal.restart.
- signal handlers should always get a chance to run (when outside a
critical region). If a system call is interrupted by a signal, then
the signal handler will run before the call is restarted or OS.SysError is raised; that is, before the Signal.restart
check.
- a system call that must be restarted while in a critical section
will be restarted with the handled signals blocked (and the
previously blocked signals remembered). This encourages the system
call to complete, allowing the program to make progess towards
leaving the critical section where the signal can be handled. If
the system call completes, the set of blocked signals are restored
to those previously blocked.
- type t
-
the type of signals.
- type Handler.t
-
the type of signal handlers.
- Handler.default
-
handles the signal with the default action.
- Handler.handler f
-
returns a handler h such that when a signal s is handled
by h, f will be passed the thread that was interrupted by
s and should return the thread that will resume execution.
- Handler.ignore
-
is a handler that will ignore the signal.
- Handler.isDefault
-
returns true if the handler is the default handler.
- Handler.isIgnore
-
returns true if the handler is the ignore handler.
- Handler.simple f
-
returns a handler that executes f () and does not switch
threads.
- type Mask.t
-
the type of signal masks, which are sets of blocked signals.
- Mask.all
-
a mask of all signals.
- Mask.allBut l
-
a mask of all signals except for those in l.
- Mask.block m
-
block all signals in m.
- Mask.getBlocked ()
-
get the signal mask m, i.e. a signal is blocked if and only
if it is in m.
- Mask.isMember (m, s)
-
returns true if the signal s is in m.
- Mask.none
-
a mask of no signals.
- Mask.setBlocked m
-
set the signal mask to m, i.e. a signal is blocked if and only
if it is in m.
- Mask.some l
-
a mask of the signals in l.
- Mask.unblock m
-
unblock all signals in m.
- getHandler s
-
returns the current handler for signal s.
- handled
-
returns the signal mask m corresponding to the currently handled
signals; i.e., a signal is handled if and only if it is im m.
- prof
-
SIGPROF, the profiling signal.
- restart
-
dynamically determines the behavior of interrupted system calls; when
true, interrupted system calls are restarted; when false,
interrupted system calls raise OS.SysError.
- setHandler (s, h)
-
sets the handler for signal s to h.
- suspend m
-
temporarily sets the signal mask to m and suspends until an
unmasked signal is received and handled, at which point suspend resets
the mask and returns.
- vtalrm
-
SIGVTALRM, the signal for virtual timers.
signature MLTON_SOCKET =
sig
structure Address:
sig
type t = word
end
structure Host:
sig
type t = {name: string}
val getByAddress: Address.t -> t option
val getByName: string -> t option
end
structure Port:
sig
type t = int
end
type t
val accept: t -> Address.t * Port.t * TextIO.instream * TextIO.outstream
val connect: string * Port.t -> TextIO.instream * TextIO.outstream
val listen: unit -> Port.t * t
val listenAt: Port.t -> t
val shutdownRead: TextIO.instream -> unit
val shutdownWrite: TextIO.outstream -> unit
end
This module contains a bare minimum of functionality to do TCP/IP
programming. This module is implemented on top of the Socket
module of the Standard Basis Library. We encourage you to use the
standard Socket module, since we may eliminate MLton.Socket some day.
- type Address.t
-
the type of IP addresses.
- Host.getByAddress a
-
lookup the hostname (using gethostbyaddr) corresponding to a.
- Host.getByName s
-
lookup the hostname (using gethostbyname) corresponding to s.
- type Port.t
-
the type of TCP ports.
- type t
-
the type of sockets.
- accept s
-
accept a connection on socket s and return the address and
port of the connecting socket, as well as streams corresponding to the
connection.
- connect (h, p)
-
connect to host h on port p, returning the streams
corresponding to the connection.
- listen ()
-
listen to a port chosen by the system. Returns the port and the socket.
- listenAt p
-
listen to port p. Returns the socket.
- shutdownRead ins
-
cause the read part of the socket associated with ins to be shutdown.
- shutdownWrite out
-
cause the write part of the socket associated with out to be shutdown.
signature MLTON_SYSLOG =
sig
type openflag
val CONS : openflag
val NDELAY : openflag
val PERROR : openflag
val PID : openflag
type facility
val AUTHPRIV : facility
val CRON : facility
val DAEMON : facility
val KERN : facility
val LOCAL0 : facility
val LOCAL1 : facility
val LOCAL2 : facility
val LOCAL3 : facility
val LOCAL4 : facility
val LOCAL5 : facility
val LOCAL6 : facility
val LOCAL7 : facility
val LPR : facility
val MAIL : facility
val NEWS : facility
val SYSLOG : facility
val USER : facility
val UUCP : facility
type loglevel
val EMERG : loglevel
val ALERT : loglevel
val CRIT : loglevel
val ERR : loglevel
val WARNING : loglevel
val NOTICE : loglevel
val INFO : loglevel
val DEBUG : loglevel
val closelog: unit -> unit
val log: loglevel * string -> unit
val openlog: string * openflag list * facility -> unit
end
MLton.Syslog is a complete interface to the system logging
facilities. See man 3 syslog for more details.
-
closelog ()
-
close the connection to the system logger.
- log (l, s)
-
log message s at a loglevel l.
- openlog (name, flags, facility)
-
open a connection to the system logger. name will be prefixed to each
message, and is typically set to the program name.
signature MLTON_TEXT_IO =
MLTON_IO
where type instream = TextIO.instream
where type outstream = TextIO.outstream
See Section 10.2.9.
signature MLTON_THREAD =
sig
structure AtomicState :
sig
datatype t = NonAtomic | Atomic of int
end
val atomicBegin: unit -> unit
val atomicEnd: unit -> unit
val atomically: (unit -> 'a) -> 'a
val atomicState: unit -> AtomicState.t
structure Runnable :
sig
type t
end
type 'a t
val new: ('a -> unit) -> 'a t
val prepend: 'a t * ('b -> 'a) -> 'b t
val prepare: 'a t * 'a -> Runnable.t
val switch: ('a t -> Runnable.t) -> 'a
val atomicSwitch: ('a t -> Runnable.t) -> 'a
end
Threads are data structures that represent a paused computation.
Runnable threads are threads that will begin or continue computing when
switched to. MLton.Thread does not include a default
scheduling mechanism, but it can be used to implement both preemptive
and non-preemptive threads. For examples, see thread1.sml and
thread2.sml in the examples directory.
- type AtomicState.t
-
the type of atomic states.
- atomicBegin ()
-
begin a critical section.
- atomicEnd ()
-
end a critical section.
- atomically f
-
runs f in a critical section.
- atomicState ()
-
return the current atomic state.
- type Runnable.t
-
the type of threads that can be resumed.
- type 'a t
-
the type of threads that expect a value of type 'a.
- new f
-
create a new thread that, when run, applies f to the value given
to the thread. f must terminate by switching to another
thread or exiting the process.
- prepend (t, f)
-
create a new thread (destroying t in the process) that first
applies f to the value given to the thread and then continues
with t. This is a constant time operation.
- prepare (t, v)
-
prepare a new runnable thread (destroying t in the process)
that will evaluate t on v.
- switch f
-
apply f to the current thread to get rt, and then start
running thread rt. It is an error for f to
perform another switch. f is guaranteed to run
atomically.
- atomicSwitch f
-
as switch, but assumes an atomic calling context. Upon switching back to the current thread, an implicit atomicEnd is
performed.
signature MLTON_VECTOR =
sig
val unfoldi: int * 'b * (int * 'b -> 'a * 'b) -> 'a vector
end
- unfoldi (n, b, f)
-
construct a vector v of a length n, whose elements vi are determined
by the equations b0 = b and (vi, bi+1) = f (i, bi).
signature MLTON_WEAK =
sig
type 'a t
val get: 'a t -> 'a option
val new: 'a -> 'a t
end
A weak pointer is a pointer to an object that is nulled if the
object becomes unreachable due to garbage collection. The weak
pointer does not itself cause the object it points to be retained by
the garbage collector -- only other strong pointers can do that.
For objects that are not allocated in the heap, like integers, a weak
pointer will always be nulled. So, if w: int Weak.t then
Weak.get w = NONE.
-
type 'a t
-
the type of weak pointers to objects of type 'a
- get w
-
returns NONE if the object pointed to by w no longer
exists. Otherwise, returns SOME of the object pointed to by
w.
- new x
-
returns a weak pointer to x.
10.2.26 MLton.Word, MLton.Word8
signature MLTON_WORD =
sig
type t
val rol: t * word -> t
val ror: t * word -> t
end
-
type t
-
the type of words. For MLton.Word this is Word.word, for
MLton.Word8 this is Word8.word.
- rol (w, w')
-
rotate left (circular).
- ror (w, w')
-
rotate right (circular).
signature MLTON_WORLD =
sig
datatype status = Clone | Original
val load: string -> 'a
val save: string -> status
val saveThread: string * Thread.Runnable.t -> unit
end
-
datatype status
-
used to specify whether a world is original or restarted (a clone).
- load f
-
load the saved computation from file f.
- save f
-
save the entire state of the computation to
the file f. The computation can then be restarted at a later
time using World.load or the load-world runtime system
option. The call to save in the original computation returns
Original and the call in the restarted world returns Clone. The following example is a transcript run in the examples/save-world directory.
% mlton save-world.sml
% save-world
I am the original
% save-world @MLton load-world world --
I am the clone
- saveThread (f, rt)
-
save the entire state of the computation to
the file f that will resume with thread rt upon restart.
10.3 SMLofNJ: SML_OF_NJ
signature SML_OF_NJ =
sig
structure Cont:
sig
type 'a cont
val callcc: ('a cont -> 'a) -> 'a
val throw: 'a cont -> 'a -> 'b
end
structure SysInfo:
sig
exception UNKNOWN
datatype os_kind = BEOS | MACOS | OS2 | UNIX | WIN32
val getHostArch: unit -> string
val getOSKind: unit -> os_kind
val getOSName: unit -> string
end
val exnHistory: exn -> string list
val exportFn: string * (string * string list -> OS.Process.status) -> unit
val exportML: string -> bool
val getAllArgs: unit -> string list
val getArgs: unit -> string list
val getCmdName: unit -> string
end
SMLofNJ implements a subset of the structure of the same name
provided in Standard ML of New Jersey. It is included to make it
easier to port programs between the two systems. The semantics of
these functions may be different than in SML/NJ.
- structure Cont
-
implements continuations.
- SysInfo.getHostArch ()
-
returns the string for the architecture.
- SysInfo.getOSKind
-
returns UNIX.
- SysInfo.getOSName ()
-
returns the string for the host.
- exnHistory
-
the same as MLton.Exn.history.
- getCmdName ()
-
the same as CommandLine.name ().
- getArgs ()
-
the same as CommandLine.arguments ().
- getAllArgs ()
-
the same as getCmdName() :: getArgs().
- exportFn f
-
save the state of the computation to a file that will apply f to
the command-line arguments upon restart.
- exportML f
-
save the state of the computation to file f and continue.
Return true in the restarted computation and false in the
continuing computation.
10.4 Unsafe: UNSAFE
This module is a subset of the Unsafe module provided by
SML/NJ.
signature UNSAFE_MONO_ARRAY =
sig
type array
type elem
val create: int -> array
val sub: array * int -> elem
val update: array * int * elem -> unit
end
signature UNSAFE_MONO_VECTOR =
sig
type elem
type vector
val sub: vector * int -> elem
end
signature UNSAFE =
sig
structure Array:
sig
val create: int * 'a -> 'a array
val sub: 'a array * int -> 'a
val update: 'a array * int * 'a -> unit
end
structure CharArray: UNSAFE_MONO_ARRAY
structure CharVector: UNSAFE_MONO_VECTOR
structure Real64Array: UNSAFE_MONO_ARRAY
structure Vector:
sig
val sub: 'a vector * int -> 'a
end
structure Word8Array: UNSAFE_MONO_ARRAY
structure Word8Vector: UNSAFE_MONO_VECTOR
end