Skip to content

Commit 25bbdb2

Browse files
committed
---
yaml --- r: 42479 b: refs/heads/try c: db1abbe h: refs/heads/master i: 42477: 80fbeec 42475: 3004f0e 42471: ec23b11 42463: dca9d33 v: v3
1 parent db80bf0 commit 25bbdb2

Some content is hidden

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

77 files changed

+1235
-1934
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
refs/heads/master: 19dfec2aaf746535de1521f68421f9980dbf25de
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 2f46b763da2c098913884f101b6d71d69af41b49
5-
refs/heads/try: 1244c0b6fd8325e1eab274e6d9b989e1ee1e2c57
5+
refs/heads/try: db1abbec4ca9f18a224441c483cf23bb4f8361fd
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: a810c03263670238bccd64cabb12a23a46e3a278

branches/try/doc/tutorial.md

Lines changed: 9 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -863,34 +863,11 @@ allocating memory and indirecting through a pointer. But for big structs, or
863863
those with mutable fields, it can be useful to have a single copy on
864864
the stack or on the heap, and refer to that through a pointer.
865865

866-
Whenever memory is allocated on the heap, the program needs a strategy to
867-
dispose of the memory when no longer needed. Most languages, such as Java or
868-
Python, use *garbage collection* for this, a strategy in which the program
869-
periodically searches for allocations that are no longer reachable in order
870-
to dispose of them. Other languages, such as C, use *manual memory
871-
management*, which relies on the programmer to specify when memory should be
872-
reclaimed.
873-
874-
Rust is in a different position. It differs from the garbage-collected
875-
environments in that allows the programmer to choose the disposal
876-
strategy on an object-by-object basis. Not only does this have benefits for
877-
performance, but we will later see that this model has benefits for
878-
concurrency as well, by making it possible for the Rust compiler to detect
879-
data races at compile time. Rust also differs from the manually managed
880-
languages in that it is *safe*—it uses a [pointer lifetime
881-
analysis][borrow] to ensure that manual memory management cannot cause memory
882-
errors at runtime.
883-
884-
[borrow]: tutorial-borrowed-ptr.html
885-
886-
The cornerstone of Rust's memory management is the concept of a *smart
887-
pointer*—a pointer type that indicates the lifetime of the object it points
888-
to. This solution is familiar to C++ programmers; Rust differs from C++,
889-
however, in that a small set of smart pointers are built into the language.
890-
The safe pointer types are `@T`, for *managed* boxes allocated on the *local
891-
heap*, `~T`, for *uniquely-owned* boxes allocated on the *exchange
892-
heap*, and `&T`, for *borrowed* pointers, which may point to any memory, and
893-
whose lifetimes are governed by the call stack.
866+
Rust supports several types of pointers. The safe pointer types are
867+
`@T`, for managed boxes allocated on the local heap, `~T`, for
868+
uniquely-owned boxes allocated on the exchange heap, and `&T`, for
869+
borrowed pointers, which may point to any memory, and whose lifetimes
870+
are governed by the call stack.
894871

895872
All pointer types can be dereferenced with the `*` unary operator.
896873

@@ -942,17 +919,7 @@ node2.next = SomeNode(node3);
942919
node3.prev = SomeNode(node2);
943920
~~~
944921

945-
Managed boxes never cross task boundaries. This has several benefits for
946-
performance:
947-
948-
* The Rust garbage collector does not need to stop multiple threads in order
949-
to collect garbage.
950-
951-
* You can separate your application into "real-time" tasks that do not use
952-
the garbage collector and "non-real-time" tasks that do, and the real-time
953-
tasks will not be interrupted by the non-real-time tasks.
954-
955-
C++ programmers will recognize `@T` as similar to `std::shared_ptr<T>`.
922+
Managed boxes never cross task boundaries.
956923

957924
> ***Note:*** Currently, the Rust compiler generates code to reclaim
958925
> managed boxes through reference counting and a cycle collector, but
@@ -989,19 +956,10 @@ let z = *x + *y;
989956
assert z == 20;
990957
~~~~
991958

992-
When they do not contain any managed boxes, owned boxes can be sent
993-
to other tasks. The sending task will give up ownership of the box
959+
Owned boxes, when they do not contain any managed boxes, can be sent
960+
to other tasks. The sending task will give up ownership of the box,
994961
and won't be able to access it afterwards. The receiving task will
995-
become the sole owner of the box. This prevents *data races*—errors
996-
that could otherwise result from multiple tasks working on the same
997-
data without synchronization.
998-
999-
When an owned pointer goes out of scope or is overwritten, the object
1000-
it points to is immediately freed. Effective use of owned boxes can
1001-
therefore be an efficient alternative to garbage collection.
1002-
1003-
C++ programmers will recognize `~T` as similar to `std::unique_ptr<T>`
1004-
(or `std::auto_ptr<T>` in C++03 and below).
962+
become the sole owner of the box.
1005963

1006964
## Borrowed pointers
1007965

branches/try/src/libcore/at_vec.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ pub mod raw {
216216
}
217217

218218
pub unsafe fn push_slow<T>(v: &mut @[const T], initval: T) {
219-
reserve_at_least(&mut *v, v.len() + 1u);
219+
reserve_at_least(v, v.len() + 1u);
220220
push_fast(v, move initval);
221221
}
222222

@@ -234,7 +234,7 @@ pub mod raw {
234234
pub unsafe fn reserve<T>(v: &mut @[const T], n: uint) {
235235
// Only make the (slow) call into the runtime if we have to
236236
if capacity(*v) < n {
237-
let ptr: **VecRepr = transmute(v);
237+
let ptr: **VecRepr = transmute(copy v);
238238
rustrt::vec_reserve_shared_actual(sys::get_type_desc::<T>(),
239239
ptr, n as libc::size_t);
240240
}

branches/try/src/libcore/core.rc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ pub mod at_vec;
9595
pub mod str;
9696

9797
pub mod ptr;
98-
pub mod owned;
9998
pub mod managed;
99+
pub mod owned;
100100

101101

102102
/* Core language traits */

branches/try/src/libcore/managed.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,7 @@
1414
#[forbid(deprecated_mode)];
1515
#[forbid(deprecated_pattern)];
1616

17-
use cast::transmute;
1817
use cmp::{Eq, Ord};
19-
use managed::raw::BoxRepr;
2018
use prelude::*;
2119
use ptr;
2220

branches/try/src/libcore/private.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ use task;
2828
use task::{TaskBuilder, atomically};
2929
use uint;
3030

31+
#[path = "private/at_exit.rs"]
32+
pub mod at_exit;
33+
#[path = "private/global.rs"]
34+
pub mod global;
35+
3136
extern mod rustrt {
3237
#[legacy_exports];
3338
unsafe fn rust_task_weaken(ch: rust_port_id);
@@ -519,6 +524,12 @@ pub unsafe fn clone_shared_mutable_state<T: Owned>(rc: &SharedMutableState<T>)
519524
ArcDestruct((*rc).data)
520525
}
521526

527+
impl<T: Owned> SharedMutableState<T>: Clone {
528+
fn clone(&self) -> SharedMutableState<T> unsafe {
529+
clone_shared_mutable_state(self)
530+
}
531+
}
532+
522533
/****************************************************************************/
523534

524535
#[allow(non_camel_case_types)] // runtime type
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
use sys;
2+
use cast;
3+
use ptr;
4+
use task;
5+
use uint;
6+
use vec;
7+
use rand;
8+
use libc::{c_void, size_t};
9+
10+
/**
11+
Register a function to be run during runtime shutdown.
12+
13+
After all non-weak tasks have exited, registered exit functions will
14+
execute, in random order, on the primary scheduler. Each function runs
15+
in its own unsupervised task.
16+
*/
17+
pub fn at_exit(f: ~fn()) unsafe {
18+
let runner: &fn(*ExitFunctions) = exit_runner;
19+
let runner_pair: sys::Closure = cast::transmute(runner);
20+
let runner_ptr = runner_pair.code;
21+
let runner_ptr = cast::transmute(runner_ptr);
22+
rustrt::rust_register_exit_function(runner_ptr, ~f);
23+
}
24+
25+
// NB: The double pointer indirection here is because ~fn() is a fat
26+
// pointer and due to FFI problems I am more comfortable making the
27+
// interface use a normal pointer
28+
extern mod rustrt {
29+
fn rust_register_exit_function(runner: *c_void, f: ~~fn());
30+
}
31+
32+
struct ExitFunctions {
33+
// The number of exit functions
34+
count: size_t,
35+
// The buffer of exit functions
36+
start: *~~fn()
37+
}
38+
39+
fn exit_runner(exit_fns: *ExitFunctions) unsafe {
40+
let exit_fns = &*exit_fns;
41+
let count = (*exit_fns).count;
42+
let start = (*exit_fns).start;
43+
44+
// NB: from_buf memcpys from the source, which will
45+
// give us ownership of the array of functions
46+
let mut exit_fns_vec = vec::from_buf(start, count as uint);
47+
// Let's not make any promises about execution order
48+
rand::Rng().shuffle_mut(exit_fns_vec);
49+
50+
debug!("running %u exit functions", exit_fns_vec.len());
51+
52+
while exit_fns_vec.is_not_empty() {
53+
match exit_fns_vec.pop() {
54+
~f => {
55+
task::task().supervised().spawn(f);
56+
}
57+
}
58+
}
59+
}
60+
61+
#[abi = "rust-intrinsic"]
62+
pub extern mod rusti {
63+
fn move_val_init<T>(dst: &mut T, -src: T);
64+
fn init<T>() -> T;
65+
}
66+
67+
#[test]
68+
fn test_at_exit() {
69+
let i = 10;
70+
do at_exit {
71+
debug!("at_exit1");
72+
assert i == 10;
73+
}
74+
}
75+
76+
#[test]
77+
fn test_at_exit_many() {
78+
let i = 10;
79+
for uint::range(20, 100) |j| {
80+
do at_exit {
81+
debug!("at_exit2");
82+
assert i == 10;
83+
assert j > i;
84+
}
85+
}
86+
}

0 commit comments

Comments
 (0)