about summary refs log tree commit diff
path: root/src/doc
diff options
context:
space:
mode:
authorJeremyLetang <letang.jeremy@gmail.com>2014-01-30 15:04:47 -0500
committerJeremyLetang <letang.jeremy@gmail.com>2014-02-05 11:56:04 -0500
commitdd21a51d294ad9843d61b7f2016957a279b0d64f (patch)
treeac8a5dae28d90c9168b653d19cc879eab18c7b24 /src/doc
parented885e35fe91c12892bbf1254b4bc6259cc96eee (diff)
move concurrent stuff from libextra to libsync
Diffstat (limited to 'src/doc')
-rw-r--r--src/doc/guide-tasks.md108
-rw-r--r--src/doc/index.md1
2 files changed, 76 insertions, 33 deletions
diff --git a/src/doc/guide-tasks.md b/src/doc/guide-tasks.md
index c3bdbe3a3ee..387f481025d 100644
--- a/src/doc/guide-tasks.md
+++ b/src/doc/guide-tasks.md
@@ -39,7 +39,7 @@ data through the global _exchange heap_.
 
 While Rust's type system provides the building blocks needed for safe
 and efficient tasks, all of the task functionality itself is implemented
-in the standard and extra libraries, which are still under development
+in the standard and sync libraries, which are still under development
 and do not always present a consistent or complete interface.
 
 For your reference, these are the standard modules involved in Rust
@@ -47,18 +47,43 @@ concurrency at this writing:
 
 * [`std::task`] - All code relating to tasks and task scheduling,
 * [`std::comm`] - The message passing interface,
-* [`extra::comm`] - Additional messaging types based on `std::comm`,
-* [`extra::sync`] - More exotic synchronization tools, including locks,
-* [`extra::arc`] - The Arc (atomically reference counted) type,
-  for safely sharing immutable data,
-* [`extra::future`] - A type representing values that may be computed concurrently and retrieved at a later time.
+* [`sync::DuplexStream`] - An extension of `pipes::stream` that allows both sending and receiving,
+* [`sync::SyncChan`] - An extension of `pipes::stream` that provides synchronous message sending,
+* [`sync::SyncPort`] - An extension of `pipes::stream` that acknowledges each message received,
+* [`sync::rendezvous`] - Creates a stream whose channel, upon sending a message, blocks until the 
+    message is received.
+* [`sync::Arc`] - The Arc (atomically reference counted) type, for safely sharing immutable data,
+* [`sync::RWArc`] - A dual-mode Arc protected by a reader-writer lock,
+* [`sync::MutexArc`] - An Arc with mutable data protected by a blocking mutex,
+* [`sync::Semaphore`] - A counting, blocking, bounded-waiting semaphore,
+* [`sync::Mutex`] - A blocking, bounded-waiting, mutual exclusion lock with an associated 
+    FIFO condition variable,
+* [`sync::RWLock`] - A blocking, no-starvation, reader-writer lock with an associated condvar,
+* [`sync::Barrier`] - A barrier enables multiple tasks to synchronize the beginning
+    of some computation,
+* [`sync::TaskPool`] - A task pool abstraction,
+* [`sync::Future`] - A type encapsulating the result of a computation which may not be complete,
+* [`sync::one`] - A "once initialization" primitive
+* [`sync::mutex`] - A proper mutex implementation regardless of the "flavor of task" which is
+    acquiring the lock.
 
 [`std::task`]: std/task/index.html
 [`std::comm`]: std/comm/index.html
-[`extra::comm`]: extra/comm/index.html
-[`extra::sync`]: extra/sync/index.html
-[`extra::arc`]: extra/arc/index.html
-[`extra::future`]: extra/future/index.html
+[`sync::DuplexStream`]: sync/struct.DuplexStream.html
+[`sync::SyncChan`]: sync/struct.SyncChan.html
+[`sync::SyncPort`]: sync/struct.SyncPort.html
+[`sync::rendezvous`]: sync/fn.rendezvous.html
+[`sync::Arc`]: sync/struct.Arc.html
+[`sync::RWArc`]: sync/struct.RWArc.html
+[`sync::MutexArc`]: sync/struct.MutexArc.html
+[`sync::Semaphore`]: sync/struct.Semaphore.html
+[`sync::Mutex`]: sync/struct.Mutex.html
+[`sync::RWLock`]: sync/struct.RWLock.html
+[`sync::Barrier`]: sync/struct.Barrier.html
+[`sync::TaskPool`]: sync/struct.TaskPool.html
+[`sync::Future`]: sync/struct.Future.html
+[`sync::one`]: sync/one/index.html
+[`sync::mutex`]: sync/mutex/index.html
 
 # Basics
 
@@ -254,21 +279,25 @@ let result = ports.iter().fold(0, |accum, port| accum + port.recv() );
 ~~~
 
 ## Backgrounding computations: Futures
-With `extra::future`, rust has a mechanism for requesting a computation and getting the result
+With `sync::Future`, rust has a mechanism for requesting a computation and getting the result
 later.
 
 The basic example below illustrates this.
 
 ~~~
+# extern mod sync;
+
+# fn main() {
 # fn make_a_sandwich() {};
 fn fib(n: u64) -> u64 {
     // lengthy computation returning an uint
     12586269025
 }
 
-let mut delayed_fib = extra::future::Future::spawn(proc() fib(50));
+let mut delayed_fib = sync::Future::spawn(proc() fib(50));
 make_a_sandwich();
 println!("fib(50) = {:?}", delayed_fib.get())
+# }
 ~~~
 
 The call to `future::spawn` returns immediately a `future` object regardless of how long it
@@ -281,6 +310,7 @@ Here is another example showing how futures allow you to background computations
 be distributed on the available cores.
 
 ~~~
+# extern mod sync;
 # use std::vec;
 fn partial_sum(start: uint) -> f64 {
     let mut local_sum = 0f64;
@@ -291,7 +321,7 @@ fn partial_sum(start: uint) -> f64 {
 }
 
 fn main() {
-    let mut futures = vec::from_fn(1000, |ind| extra::future::Future::spawn( proc() { partial_sum(ind) }));
+    let mut futures = vec::from_fn(1000, |ind| sync::Future::spawn( proc() { partial_sum(ind) }));
 
     let mut final_res = 0f64;
     for ft in futures.mut_iter()  {
@@ -309,16 +339,17 @@ add up to a significant amount of wasted memory and would require copying the sa
 necessary.
 
 To tackle this issue, one can use an Atomically Reference Counted wrapper (`Arc`) as implemented in
-the `extra` library of Rust. With an Arc, the data will no longer be copied for each task. The Arc
+the `sync` library of Rust. With an Arc, the data will no longer be copied for each task. The Arc
 acts as a reference to the shared data and only this reference is shared and cloned.
 
 Here is a small example showing how to use Arcs. We wish to run concurrently several computations on
 a single large vector of floats. Each task needs the full vector to perform its duty.
 
 ~~~
+# extern mod sync;
 # use std::vec;
 # use std::rand;
-use extra::arc::Arc;
+use sync::Arc;
 
 fn pnorm(nums: &~[f64], p: uint) -> f64 {
     nums.iter().fold(0.0, |a,b| a+(*b).powf(&(p as f64)) ).powf(&(1.0 / (p as f64)))
@@ -348,23 +379,29 @@ at the power given as argument and takes the inverse power of this value). The A
 created by the line
 
 ~~~
-# use extra::arc::Arc;
+# extern mod sync;
+# use sync::Arc;
 # use std::vec;
 # use std::rand;
+# fn main() {
 # let numbers = vec::from_fn(1000000, |_| rand::random::<f64>());
 let numbers_arc=Arc::new(numbers);
+# }
 ~~~
 
 and a clone of it is sent to each task
 
 ~~~
-# use extra::arc::Arc;
+# extern mod sync;
+# use sync::Arc;
 # use std::vec;
 # use std::rand;
+# fn main() {
 # let numbers=vec::from_fn(1000000, |_| rand::random::<f64>());
 # let numbers_arc = Arc::new(numbers);
 # let (port, chan)  = Chan::new();
 chan.send(numbers_arc.clone());
+# }
 ~~~
 
 copying only the wrapper and not its contents.
@@ -372,15 +409,18 @@ copying only the wrapper and not its contents.
 Each task recovers the underlying data by
 
 ~~~
-# use extra::arc::Arc;
+# extern mod sync;
+# use sync::Arc;
 # use std::vec;
 # use std::rand;
+# fn main() {
 # let numbers=vec::from_fn(1000000, |_| rand::random::<f64>());
 # let numbers_arc=Arc::new(numbers);
 # let (port, chan)  = Chan::new();
 # chan.send(numbers_arc.clone());
 # let local_arc : Arc<~[f64]> = port.recv();
 let task_numbers = local_arc.get();
+# }
 ~~~
 
 and can use it as if it were local.
@@ -450,7 +490,7 @@ proceed).
 
 A very common thing to do is to spawn a child task where the parent
 and child both need to exchange messages with each other. The
-function `extra::comm::DuplexStream()` supports this pattern.  We'll
+function `sync::comm::DuplexStream()` supports this pattern.  We'll
 look briefly at how to use it.
 
 To see how `DuplexStream()` works, we will create a child task
@@ -458,17 +498,19 @@ that repeatedly receives a `uint` message, converts it to a string, and sends
 the string in response.  The child terminates when it receives `0`.
 Here is the function that implements the child task:
 
-~~~{.ignore .linked-failure}
-# use extra::comm::DuplexStream;
-# use std::uint;
-fn stringifier(channel: &DuplexStream<~str, uint>) {
-    let mut value: uint;
-    loop {
-        value = channel.recv();
-        channel.send(uint::to_str(value));
-        if value == 0 { break; }
+~~~
+# extern mod sync;
+# fn main() {
+# use sync::DuplexStream;
+    fn stringifier(channel: &DuplexStream<~str, uint>) {
+        let mut value: uint;
+        loop {
+            value = channel.recv();
+            channel.send(value.to_str());
+            if value == 0 { break; }
+        }
     }
-}
+# }
 ~~~~
 
 The implementation of `DuplexStream` supports both sending and
@@ -481,15 +523,15 @@ response itself is simply the stringified version of the received value,
 
 Here is the code for the parent task:
 
-~~~{.ignore .linked-failure}
+~~~
+# extern mod sync;
 # use std::task::spawn;
-# use std::uint;
-# use extra::comm::DuplexStream;
+# use sync::DuplexStream;
 # fn stringifier(channel: &DuplexStream<~str, uint>) {
 #     let mut value: uint;
 #     loop {
 #         value = channel.recv();
-#         channel.send(uint::to_str(value));
+#         channel.send(value.to_str());
 #         if value == 0u { break; }
 #     }
 # }
diff --git a/src/doc/index.md b/src/doc/index.md
index 9915d67bfca..5aa92c9fec4 100644
--- a/src/doc/index.md
+++ b/src/doc/index.md
@@ -43,6 +43,7 @@ li {list-style-type: none; }
 * [The `semver` version collation library](semver/index.html)
 * [The `term` terminal-handling library](term/index.html)
 * [The UUID library](uuid/index.html)
+* [The `sync` library for concurrency-enabled mechanisms and primitives](sync/index.html)
 
 # Tooling