]> gitweb.factorcode.org Git - factor.git/blob - basis/threads/threads-docs.factor
3c4715d3e3de43833030f4e0da20a7b4bba28db0
[factor.git] / basis / threads / threads-docs.factor
1 USING: help.markup help.syntax kernel kernel.private io
2 threads.private continuations dlists init quotations strings
3 assocs heaps boxes namespaces deques ;
4 IN: threads
5
6 ARTICLE: "threads-start/stop" "Starting and stopping threads"
7 "Spawning new threads:"
8 { $subsection spawn }
9 { $subsection spawn-server }
10 "Creating and spawning a thread can be factored out into two separate steps:"
11 { $subsection <thread> }
12 { $subsection (spawn) }
13 "Threads stop either when the quotation given to " { $link spawn } " returns, or when the following word is called:"
14 { $subsection stop }
15 "If the image is saved and started again, all runnable threads are stopped. Vocabularies wishing to have a background thread always running should use " { $link add-init-hook } "." ;
16
17 ARTICLE: "threads-yield" "Yielding and suspending threads"
18 "Yielding to other threads:"
19 { $subsection yield }
20 "Sleeping for a period of time:"
21 { $subsection sleep }
22 "Interrupting sleep:"
23 { $subsection interrupt }
24 "Threads can be suspended and woken up at some point in the future when a condition is satisfied:"
25 { $subsection suspend }
26 { $subsection resume }
27 { $subsection resume-with } ;
28
29 ARTICLE: "thread-state" "Thread-local state and variables"
30 "Threads form a class of objects:"
31 { $subsection thread }
32 "The current thread:"
33 { $subsection self }
34 "Thread-local variables:"
35 { $subsection tnamespace }
36 { $subsection tget }
37 { $subsection tset }
38 { $subsection tchange }
39 "Each thread has its own independent set of thread-local variables and newly-spawned threads begin with an empty set."
40 $nl
41 "Global hashtable of all threads, keyed by " { $snippet "id" } ":"
42 { $subsection threads }
43 "Threads have an identity independent of continuations. If a continuation is refied in one thread and then resumed in another thread, the code running in that continuation will observe a change in the value output by " { $link self } "." ;
44
45 ARTICLE: "thread-impl" "Thread implementation"
46 "Thread implementation:"
47 { $subsection run-queue }
48 { $subsection sleep-queue } ;
49
50 ARTICLE: "threads" "Lightweight co-operative threads"
51 "Factor supports lightweight co-operative threads implemented on top of continuations. A thread will yield while waiting for input/output operations to complete, or when a yield has been explicitly requested."
52 $nl
53 "Factor threads are very lightweight. Each thread can take as little as 900 bytes of memory. This library has been tested running hundreds of thousands of simple threads."
54 $nl
55 "Words for working with threads are in the " { $vocab-link "threads" } " vocabulary."
56 { $subsection "threads-start/stop" }
57 { $subsection "threads-yield" }
58 { $subsection "thread-state" }
59 { $subsection "thread-impl" } ;
60
61 ABOUT: "threads"
62
63 HELP: thread
64 { $class-description "A thread. The slots are as follows:"
65     { $list
66         { { $snippet "id" } " - a unique identifier assigned to each thread." }
67         { { $snippet "name" } " - the name passed to " { $link spawn } "." }
68         { { $snippet "quot" } " - the initial quotation passed to " { $link spawn } "." }
69         { { $snippet "continuation" } " - a " { $link box } "; if the thread is ready to run, the box holds the continuation, otherwise it is empty." }
70     }
71 } ;
72
73 HELP: self
74 { $values { "thread" thread } }
75 { $description "Pushes the currently-running thread." } ;
76
77 HELP: <thread>
78 { $values { "quot" quotation } { "name" string } { "thread" thread } }
79 { $description "Low-level thread constructor. The thread runs the quotation when spawned."
80 $nl
81 "The name is used to identify the thread for debugging purposes; see " { $link "tools.threads" } "." }
82 { $notes "In most cases, user code should call " { $link spawn } " instead, however for control over the error handler quotation, threads can be created with " { $link <thread> } " then passed to " { $link (spawn) } "." } ;
83
84 HELP: run-queue
85 { $values { "queue" dlist } }
86 { $var-description "Global variable holding the queue of runnable threads. Calls to " { $link yield } " switch to the thread which has been in the queue for the longest period of time."
87 $nl
88 "By convention, threads are queued with " { $link push-front } 
89 " and dequed with " { $link pop-back } "." } ;
90
91 HELP: resume
92 { $values { "thread" thread } }
93 { $description "Adds a thread to the end of the run queue. The thread must have previously been suspended by a call to " { $link suspend } "." } ;
94
95 HELP: resume-with
96 { $values { "obj" object } { "thread" thread } }
97 { $description "Adds a thread to the end of the run queue together with an object to pass to the thread. The thread must have previously been suspended by a call to " { $link suspend } "; the object is returned from the " { $link suspend } " call." } ;
98
99 HELP: sleep-queue
100 { $var-description "A " { $link min-heap } " storing the queue of sleeping threads." } ;
101
102 HELP: sleep-time
103 { $values { "ms/f" "a non-negative integer or " { $link f } } }
104 { $description "Outputs the time until the next sleeping thread is scheduled to wake up, which could be zero if there are threads in the run queue, or threads which need to wake up right now. If there are no runnable or sleeping threads, outputs " { $link f } "." } ;
105
106 HELP: stop
107 { $description "Stops the current thread. The thread may be started again from another thread using " { $link (spawn) } "." } ;
108
109 HELP: yield
110 { $description "Adds the current thread to the end of the run queue, and switches to the next runnable thread." } ;
111
112 HELP: sleep-until
113 { $values { "time/f" "a non-negative integer or " { $link f } } }
114 { $description "Suspends the current thread until the given time, or indefinitely if a value of " { $link f } " is passed in."
115 $nl
116 "Other threads may interrupt the sleep by calling " { $link interrupt } "." } ;
117
118 HELP: sleep
119 { $values { "dt" "a duration" } }
120 { $description "Suspends the current thread for the given duration."
121 $nl
122 "Other threads may interrupt the sleep by calling " { $link interrupt } "." }
123 { $examples
124     { $code "USING: threads calendar ;" "10 seconds sleep" }
125 } ;
126
127 HELP: interrupt
128 { $values { "thread" thread } }
129 { $description "Interrupts a sleeping thread." } ;
130
131 HELP: suspend
132 { $values { "quot" "a quotation with stack effect " { $snippet "( thread -- )" } } { "state" string } { "obj" object } }
133 { $description "Suspends the current thread and passes it to the quotation."
134 $nl
135 "After the quotation returns, control yields to the next runnable thread and the current thread does not execute again until it is resumed, and so the quotation must arrange for another thread to later resume the suspended thread with a call to " { $link resume } " or " { $link resume-with } "."
136 $nl
137 "The status string is for debugging purposes; see " { $link "tools.threads" } "." } ;
138
139 HELP: spawn
140 { $values { "quot" quotation } { "name" string } { "thread" thread } }
141 { $description "Spawns a new thread. The thread begins executing the given quotation; the name is for debugging purposes. The new thread begins running immediately and the current thread is added to the end of the run queue."
142 $nl
143 "The new thread begins with an empty data stack, an empty retain stack, and an empty catch stack. The name stack is inherited from the parent thread but may be cleared with " { $link init-namespaces } "." }
144 { $notes
145      "The recommended way to pass data to the new thread is to explicitly construct a quotation containing the data, for example using " { $link curry } " or " { $link compose } "."
146 }
147 { $examples
148     { $code "1 2 [ + . ] 2curry \"Addition thread\" spawn" }
149 } ;
150
151 HELP: spawn-server
152 { $values { "quot" "a quotation with stack effect " { $snippet "( -- ? )" } } { "name" string } { "thread" thread } }
153 { $description "Convenience wrapper around " { $link spawn } " which repeatedly calls the quotation in a new thread until it outputs " { $link f } "." }
154 { $examples
155     "A thread that runs forever:"
156     { $code "[ do-foo-bar t ] \"Foo bar server\" spawn-server" }
157 } ;
158
159 HELP: init-threads
160 { $description "Called during startup to initialize the threading system. This word should never be called directly." } ;
161
162 HELP: tnamespace
163 { $values { "assoc" assoc } }
164 { $description "Outputs the current thread's set of thread-local variables." } ;
165
166 HELP: tget
167 { $values { "key" object } { "value" object } }
168 { $description "Outputs the value of a thread-local variable." } ;
169
170 HELP: tset
171 { $values { "value" object } { "key" object } }
172 { $description "Sets the value of a thread-local variable." } ;
173
174 HELP: tchange
175 { $values { "key" object } { "quot" "a quotation with stack effect " { $snippet "( value -- newvalue )" } } }
176 { $description "Applies the quotation to the current value of a thread-local variable, storing the result back to the same variable." } ;