Skip to content

Commit 4383169

Browse files
committed
---
yaml --- r: 148271 b: refs/heads/try2 c: dd8b011 h: refs/heads/master i: 148269: 9ae751a 148267: e5de47c 148263: ce9c9c9 148255: a726f28 v: v3
1 parent 5762a20 commit 4383169

File tree

120 files changed

+5663
-14580
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

120 files changed

+5663
-14580
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ refs/heads/snap-stage3: 78a7676898d9f80ab540c6df5d4c9ce35bb50463
55
refs/heads/try: 519addf6277dbafccbb4159db4b710c37eaa2ec5
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
8-
refs/heads/try2: a599d897fcc2c66c6ad4462d3048873bd0ed87b9
8+
refs/heads/try2: dd8b011319f5cfbfb3329d9dad185be884f3a4d6
99
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try2/configure

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -795,6 +795,7 @@ do
795795
make_dir $h/test/codegen
796796
make_dir $h/test/doc-tutorial
797797
make_dir $h/test/doc-guide-ffi
798+
make_dir $h/test/doc-guide-runtime
798799
make_dir $h/test/doc-guide-macros
799800
make_dir $h/test/doc-guide-lifetimes
800801
make_dir $h/test/doc-guide-pointers

branches/try2/doc/README.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ source code.
88
the Markdown docs (reference manual, tutorials, etc.) distributed with
99
this git repository.
1010

11+
[po4a](http://po4a.alioth.debian.org/) is required for generating translated
12+
docs from the master (English) docs.
13+
14+
[GNU gettext](http://www.gnu.org/software/gettext/) is required for managing
15+
the translation data.
16+
1117
# Building
1218

1319
To generate all the docs, just run `make docs` from the root of the repository.
@@ -38,3 +44,43 @@ http://johnmacfarlane.net/pandoc/README.html#pandocs-markdown
3844

3945
A nice quick reference (for non-pandoc markdown) is at:
4046
http://kramdown.rubyforge.org/quickref.html
47+
48+
# Notes for translators
49+
50+
Notice: The procedure described below is a work in progress. We are working on
51+
translation system but the procedure contains some manual operations for now.
52+
53+
To start the translation for a new language, see po4a.conf at first.
54+
55+
To generate .pot and .po files, do something like:
56+
57+
~~~~
58+
po4a --copyright-holder="The Rust Project Developers" \
59+
--package-name="Rust" \
60+
--package-version="0.10-pre" \
61+
-M UTF-8 -L UTF-8 \
62+
po4a.conf
63+
~~~~
64+
65+
(the version number must be changed if it is not 0.10-pre now.)
66+
67+
Now you can translate documents with .po files, commonly used with gettext. If
68+
you are not familiar with gettext-based translation, please read the online
69+
manual linked from http://www.gnu.org/software/gettext/ . We use UTF-8 as the
70+
file encoding of .po files.
71+
72+
When you want to make a commit, do the command below before staging your
73+
change:
74+
75+
~~~~
76+
for f in doc/po/**/*.po; do
77+
msgattrib --translated $f -o $f.strip
78+
if [ -e $f.strip ]; then
79+
mv $f.strip $f
80+
else
81+
rm $f
82+
fi
83+
done
84+
~~~~
85+
86+
This removes untranslated entries from .po files to save disk space.

branches/try2/doc/guide-runtime.md

Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
% A Guide to the Rust Runtime
2+
3+
Rust includes two runtime libraries in the standard distribution, which provide
4+
a unified interface to primitives such as I/O, but the language itself does not
5+
require a runtime. The compiler is capable of generating code that works in all
6+
environments, even kernel environments. Neither does the Rust language need a
7+
runtime to provide memory safety; the type system itself is sufficient to write
8+
safe code, verified statically at compile time. The runtime merely uses the
9+
safety features of the language to build a number of convenient and safe
10+
high-level abstractions.
11+
12+
That being said, code without a runtime is often very limited in what it can do.
13+
As a result, Rust's standard libraries supply a set of functionality that is
14+
normally considered the Rust runtime. This guide will discuss Rust's user-space
15+
runtime, how to use it, and what it can do.
16+
17+
# What is the runtime?
18+
19+
The Rust runtime can be viewed as a collection of code which enables services
20+
like I/O, task spawning, TLS, etc. It's essentially an ephemeral collection of
21+
objects which enable programs to perform common tasks more easily. The actual
22+
implementation of the runtime itself is mostly a sparse set of opt-in primitives
23+
that are all self-contained and avoid leaking their abstractions into libraries.
24+
25+
The current runtime is the engine behind these features (not a comprehensive
26+
list):
27+
28+
* I/O
29+
* Task spawning
30+
* Message passing
31+
* Task synchronization
32+
* Task-local storage
33+
* Logging
34+
* Local heaps (GC heaps)
35+
* Task unwinding
36+
37+
## What is the runtime accomplishing?
38+
39+
The runtime is designed with a few goals in mind:
40+
41+
* Rust libraries should work in a number of environments without having to worry
42+
about the exact details of the environment itself. Two commonly referred to
43+
environments are the M:N and 1:1 environments. Since the Rust runtime was
44+
first designed, it has supported M:N threading, and it has since gained 1:1
45+
support as well.
46+
47+
* The runtime should not enforce separate "modes of compilation" in order to
48+
work in multiple circumstances. Is it an explicit goal that you compile a Rust
49+
library once and use it forever (in all environments).
50+
51+
* The runtime should be fast. There should be no architectural design barrier
52+
which is preventing programs from running at optimal speeds. It is not a goal
53+
for the runtime to be written "as fast as can be" at every moment in time. For
54+
example, no claims will be made that the current implementation of the runtime
55+
is the fastest it will ever be. This goal is simply to prevent any
56+
architectural roadblock from hindering performance.
57+
58+
* The runtime should be nearly invisible. The design of the runtime should not
59+
encourage direct interaction with it, and using the runtime should be
60+
essentially transparent to libraries. This does not mean it should be
61+
impossible to query the runtime, but rather it should be unconventional.
62+
63+
# Architecture of the runtime
64+
65+
This section explains the current architecture of the Rust runtime. It has
66+
evolved over the development of Rust through many iterations, and this is simply
67+
the documentation of the current iteration.
68+
69+
## A local task
70+
71+
The core abstraction of the Rust runtime is the task. A task represents a
72+
"thread" of execution of Rust code, but it does not necessarily correspond to an
73+
OS thread. Most runtime services are accessed through the local task, allowing
74+
for runtime policy decisions to be made on a per-task basis.
75+
76+
A consequence of this decision is to require all Rust code using the standard
77+
library to have a local `Task` structure available to them. This `Task` is
78+
stored in the OS's thread local storage (OS TLS) to allow for efficient access
79+
to it.
80+
81+
It has also been decided that the presence or non-presence of a local `Task` is
82+
essentially the *only* assumption that the runtime can make. Almost all runtime
83+
services are routed through this local structure.
84+
85+
This requirement of a local task is a core assumption on behalf of *all* code
86+
using the standard library, hence it is defined in the standard library itself.
87+
88+
## I/O
89+
90+
When dealing with I/O in general, there are a few flavors by which it can be
91+
dealt with, and not all flavors are right for all situations. I/O is also a
92+
tricky topic that is nearly impossible to get consistent across all
93+
environments. As a result, a Rust task is not guaranteed to have access to I/O,
94+
and it is not even guaranteed what the implementation of the I/O will be.
95+
96+
This conclusion implies that I/O *cannot* be defined in the standard library.
97+
The standard library does, however, provide the interface to I/O that all Rust
98+
tasks are able to consume.
99+
100+
This interface is implemented differently for various flavors of tasks, and is
101+
designed with a focus around synchronous I/O calls. This architecture does not
102+
fundamentally prevent other forms of I/O from being defined, but it is not done
103+
at this time.
104+
105+
The I/O interface that the runtime must provide can be found in the
106+
[std::rt::rtio](std/rt/rtio/trait.IoFactory.html) module. Note that this
107+
interface is *unstable*, and likely always will be.
108+
109+
## Task Spawning
110+
111+
A frequent operation performed by tasks is to spawn a child task to perform some
112+
work. This is the means by which parallelism is enabled in Rust. This decision
113+
of how to spawn a task is not a general decision, and is hence a local decision
114+
to the task (not defined in the standard library).
115+
116+
Task spawning is interpreted as "spawning a sibling" and is enabled through the
117+
high level interface in `std::task`. The child task can be configured
118+
accordingly, and runtime implementations must respect these options when
119+
spawning a new task.
120+
121+
Another local task operation is dealing with the runnable state of the task
122+
itself. This frequently comes up when the question is "how do I block a task?"
123+
or "how do I wake up a task?". These decisions are inherently local to the task
124+
itself, yet again implying that they are not defined in the standard library.
125+
126+
## The `Runtime` trait and the `Task` structure
127+
128+
The full complement of runtime features is defined by the [`Runtime`
129+
trait](std/rt/trait.Runtime.html) and the [`Task`
130+
struct](std/rt/task/struct.Task.html). A `Task` is constant among all runtime
131+
implementations, but each runtime implements has its own implementation of the
132+
`Runtime` trait.
133+
134+
The local `Task` stores the runtime value inside of itself, and then ownership
135+
dances ensue to invoke methods on the runtime.
136+
137+
# Implementations of the runtime
138+
139+
The Rust distribution provides two implementations of the runtime. These two
140+
implementations are generally known as 1:1 threading and M:N threading.
141+
142+
As with many problems in computer science, there is no right answer in this
143+
question of which implementation of the runtime to choose. Each implementation
144+
has its benefits and each has its drawbacks. The descriptions below are meant to
145+
inform programmers about what the implementation provides and what it doesn't
146+
provide in order to make an informed decision about which to choose.
147+
148+
## 1:1 - using `libnative`
149+
150+
The library `libnative` is an implementation of the runtime built upon native OS
151+
threads plus libc blocking I/O calls. This is called 1:1 threading because each
152+
user-space thread corresponds to exactly one kernel thread.
153+
154+
In this model, each Rust task corresponds to one OS thread, and each I/O object
155+
essentially corresponds to a file descriptor (or the equivalent of the platform
156+
you're running on).
157+
158+
Some benefits to using libnative are:
159+
160+
* Guaranteed interop with FFI bindings. If a C library you are using blocks the
161+
thread to do I/O (such as a database driver), then this will not interfere
162+
with other Rust tasks (because only the OS thread will be blocked).
163+
* Less I/O overhead as opposed to M:N in some cases. Not all M:N I/O is
164+
guaranteed to be "as fast as can be", and some things (like filesystem APIs)
165+
are not truly asynchronous on all platforms, meaning that the M:N
166+
implementation may incur more overhead than a 1:1 implementation.
167+
168+
## M:N - using `libgreen`
169+
170+
The library `libgreen` implements the runtime with "green threads" on top of the
171+
asynchronous I/O framework [libuv][libuv]. The M in M:N threading is the number
172+
of OS threads that a process has, and the N is the number of Rust tasks. In this
173+
model, N Rust tasks are multiplexed among M OS threads, and context switching is
174+
implemented in user-space.
175+
176+
The primary concern of an M:N runtime is that a Rust task cannot block itself in
177+
a syscall. If this happens, then the entire OS thread is frozen and unavailable
178+
for running more Rust tasks, making this a (M-1):N runtime (and you can see how
179+
this can reach 0/deadlock. By using asynchronous I/O under the hood (all I/O
180+
still looks synchronous in terms of code), OS threads are never blocked until
181+
the appropriate time comes.
182+
183+
Upon reading `libgreen`, you may notice that there is no I/O implementation
184+
inside of the library, but rather just the infrastructure for maintaining a set
185+
of green schedulers which switch among Rust tasks. The actual I/O implementation
186+
is found in `librustuv` which are the Rust bindings to libuv. This distinction
187+
is made to allow for other I/O implementations not built on libuv (but none
188+
exist at this time).
189+
190+
Some benefits of using libgreen are:
191+
192+
* Fast task spawning. When using M:N threading, spawning a new task can avoid
193+
executing a syscall entirely, which can lead to more efficient task spawning
194+
times.
195+
* Fast task switching. Because context switching is implemented in user-space,
196+
all task contention operations (mutexes, channels, etc) never execute
197+
syscalls, leading to much faster implementations and runtimes. An efficient
198+
context switch also leads to higher throughput servers than 1:1 threading
199+
because tasks can be switched out much more efficiently.
200+
201+
### Pools of Schedulers
202+
203+
M:N threading is built upon the concept of a pool of M OS threads (which
204+
libgreen refers to as schedulers), able to run N Rust tasks. This abstraction is
205+
encompassed in libgreen's [`SchedPool`][schedpool] type. This type allows for
206+
fine-grained control over the pool of schedulers which will be used to run Rust
207+
tasks.
208+
209+
In addition the `SchedPool` type is the *only* way through which a new M:N task
210+
can be spawned. Sibling tasks to Rust tasks themselves (created through
211+
`std::task::spawn`) will be spawned into the same pool of schedulers that the
212+
original task was home to. New tasks must previously have some form of handle
213+
into the pool of schedulers in order to spawn a new task.
214+
215+
## Which to choose?
216+
217+
With two implementations of the runtime available, a choice obviously needs to
218+
be made to see which will be used. The compiler itself will always by-default
219+
link to one of these runtimes. At the time of this writing, the default runtime
220+
is `libgreen` but in the future this will become `libnative`.
221+
222+
Having a default decision made in the compiler is done out of necessity and
223+
convenience. The compiler's decision of runtime to link to is *not* an
224+
endorsement of one over the other. As always, this decision can be overridden.
225+
226+
For example, this program will be linked to "the default runtime"
227+
228+
~~~{.rust}
229+
fn main() {}
230+
~~~
231+
232+
Whereas this program explicitly opts into using a particular runtime
233+
234+
~~~{.rust}
235+
extern mod green;
236+
237+
#[start]
238+
fn start(argc: int, argv: **u8) -> int {
239+
do green::start(argc, argv) {
240+
main();
241+
}
242+
}
243+
244+
fn main() {}
245+
~~~
246+
247+
Both libgreen/libnative provide a top-level `start` function which is used to
248+
boot an initial Rust task in that specified runtime.
249+
250+
# Finding the runtime
251+
252+
The actual code for the runtime is spread out among a few locations:
253+
254+
* [std::rt][stdrt]
255+
* [libnative][libnative]
256+
* [libgreen][libgreen]
257+
* [librustuv][librustuv]
258+
259+
[libuv]: https://github.com/joyent/libuv/
260+
[stdrt]: std/rt/index.html
261+
[libnative]: native/index.html
262+
[libgreen]: green/index.html
263+
[librustuv]: rustuv/index.html

branches/try2/doc/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
[Packaging](guide-rustpkg.html)
2121
[Testing](guide-testing.html)
2222
[Conditions](guide-conditions.html)
23+
[Rust's Runtime](guide-runtime.html)
2324

2425
# Libraries
2526

0 commit comments

Comments
 (0)