Commit | Line | Data |
---|---|---|
7f918cf1 CE |
1 | MLtonThread |
2 | =========== | |
3 | ||
4 | [source,sml] | |
5 | ---- | |
6 | signature MLTON_THREAD = | |
7 | sig | |
8 | structure AtomicState: | |
9 | sig | |
10 | datatype t = NonAtomic | Atomic of int | |
11 | end | |
12 | ||
13 | val atomically: (unit -> 'a) -> 'a | |
14 | val atomicBegin: unit -> unit | |
15 | val atomicEnd: unit -> unit | |
16 | val atomicState: unit -> AtomicState.t | |
17 | ||
18 | structure Runnable: | |
19 | sig | |
20 | type t | |
21 | end | |
22 | ||
23 | type 'a t | |
24 | ||
25 | val atomicSwitch: ('a t -> Runnable.t) -> 'a | |
26 | val new: ('a -> unit) -> 'a t | |
27 | val prepend: 'a t * ('b -> 'a) -> 'b t | |
28 | val prepare: 'a t * 'a -> Runnable.t | |
29 | val switch: ('a t -> Runnable.t) -> 'a | |
30 | end | |
31 | ---- | |
32 | ||
33 | `MLton.Thread` provides access to MLton's user-level thread | |
34 | implementation (i.e. not OS-level threads). Threads are lightweight | |
35 | data structures that represent a paused computation. Runnable threads | |
36 | are threads that will begin or continue computing when `switch`-ed to. | |
37 | `MLton.Thread` does not include a default scheduling mechanism, but it | |
38 | can be used to implement both preemptive and non-preemptive threads. | |
39 | ||
40 | * `type AtomicState.t` | |
41 | + | |
42 | the type of atomic states. | |
43 | ||
44 | ||
45 | * `atomically f` | |
46 | + | |
47 | runs `f` in a critical section. | |
48 | ||
49 | * `atomicBegin ()` | |
50 | + | |
51 | begins a critical section. | |
52 | ||
53 | * `atomicEnd ()` | |
54 | + | |
55 | ends a critical section. | |
56 | ||
57 | * `atomicState ()` | |
58 | + | |
59 | returns the current atomic state. | |
60 | ||
61 | * `type Runnable.t` | |
62 | + | |
63 | the type of threads that can be resumed. | |
64 | ||
65 | * `type 'a t` | |
66 | + | |
67 | the type of threads that expect a value of type `'a`. | |
68 | ||
69 | * `atomicSwitch f` | |
70 | + | |
71 | like `switch`, but assumes an atomic calling context. Upon | |
72 | `switch`-ing back to the current thread, an implicit `atomicEnd` is | |
73 | performed. | |
74 | ||
75 | * `new f` | |
76 | + | |
77 | creates a new thread that, when run, applies `f` to the value given to | |
78 | the thread. `f` must terminate by `switch`ing to another thread or | |
79 | exiting the process. | |
80 | ||
81 | * `prepend (t, f)` | |
82 | + | |
83 | creates a new thread (destroying `t` in the process) that first | |
84 | applies `f` to the value given to the thread and then continues with | |
85 | `t`. This is a constant time operation. | |
86 | ||
87 | * `prepare (t, v)` | |
88 | + | |
89 | prepares a new runnable thread (destroying `t` in the process) that | |
90 | will evaluate `t` on `v`. | |
91 | ||
92 | * `switch f` | |
93 | + | |
94 | applies `f` to the current thread to get `rt`, and then start running | |
95 | thread `rt`. It is an error for `f` to perform another `switch`. `f` | |
96 | is guaranteed to run atomically. | |
97 | ||
98 | ||
99 | == Example of non-preemptive threads == | |
100 | ||
101 | [source,sml] | |
102 | ---- | |
103 | sys::[./bin/InclGitFile.py mlton master doc/examples/thread/non-preemptive-threads.sml] | |
104 | ---- | |
105 | ||
106 | ||
107 | == Example of preemptive threads == | |
108 | ||
109 | [source,sml] | |
110 | ---- | |
111 | sys::[./bin/InclGitFile.py mlton master doc/examples/thread/preemptive-threads.sml] | |
112 | ---- |