mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-01 15:01:51 +00:00
Fallout from libgreen and libnative removal
This commit is contained in:
parent
a68ec98166
commit
40c78ab037
@ -37,7 +37,7 @@
|
||||
#
|
||||
# DEPS_<crate>
|
||||
# These lists are the dependencies of the <crate> that is to be built.
|
||||
# Rust dependencies are listed bare (i.e. std, green) and native
|
||||
# Rust dependencies are listed bare (i.e. std) and native
|
||||
# dependencies have a "native:" prefix (i.e. native:hoedown). All deps
|
||||
# will be built before the crate itself is built.
|
||||
#
|
||||
@ -49,7 +49,7 @@
|
||||
# automatically generated for all stage/host/target combinations.
|
||||
################################################################################
|
||||
|
||||
TARGET_CRATES := libc std green flate arena term \
|
||||
TARGET_CRATES := libc std flate arena term \
|
||||
serialize sync getopts collections test time rand \
|
||||
log regex graphviz core rbml alloc rustrt \
|
||||
unicode
|
||||
@ -66,7 +66,6 @@ DEPS_rustrt := alloc core libc collections native:rustrt_native
|
||||
DEPS_std := core libc rand alloc collections rustrt sync unicode \
|
||||
native:rust_builtin native:backtrace
|
||||
DEPS_graphviz := std
|
||||
DEPS_green := std native:context_switch
|
||||
DEPS_syntax := std term serialize log fmt_macros arena libc
|
||||
DEPS_rustc_trans := rustc rustc_back rustc_llvm libc
|
||||
DEPS_rustc := syntax flate arena serialize getopts rbml \
|
||||
|
@ -9,8 +9,6 @@ Source layout:
|
||||
| `libcore/` | The Rust core library |
|
||||
| `libdebug/` | Debugging utilities |
|
||||
| `libstd/` | The standard library (imported and linked by default) |
|
||||
| `libgreen/` | The M:N runtime library |
|
||||
| `libnative/` | The 1:1 runtime library |
|
||||
| `libsyntax/` | The Rust parser and pretty-printer |
|
||||
| `libtest/` | Rust's test-runner code |
|
||||
| ------------------- | --------------------------------------------------------- |
|
||||
|
@ -999,14 +999,14 @@ An example of what will and will not work for `use` items:
|
||||
|
||||
```
|
||||
# #![allow(unused_imports)]
|
||||
use foo::native::start; // good: foo is at the root of the crate
|
||||
use foo::core::iter; // good: foo is at the root of the crate
|
||||
use foo::baz::foobaz; // good: foo is at the root of the crate
|
||||
|
||||
mod foo {
|
||||
extern crate native;
|
||||
extern crate core;
|
||||
|
||||
use foo::native::start; // good: foo is at crate root
|
||||
// use native::start; // bad: native is not at the crate root
|
||||
use foo::core::iter; // good: foo is at crate root
|
||||
// use core::iter; // bad: native is not at the crate root
|
||||
use self::baz::foobaz; // good: self refers to module 'foo'
|
||||
use foo::bar::foobar; // good: foo is at crate root
|
||||
|
||||
|
@ -73,7 +73,6 @@ extern crate libc;
|
||||
|
||||
// Allow testing this library
|
||||
|
||||
#[cfg(test)] extern crate native;
|
||||
#[cfg(test)] #[phase(plugin, link)] extern crate std;
|
||||
#[cfg(test)] #[phase(plugin, link)] extern crate log;
|
||||
|
||||
|
@ -31,7 +31,6 @@
|
||||
extern crate unicode;
|
||||
extern crate alloc;
|
||||
|
||||
#[cfg(test)] extern crate native;
|
||||
#[cfg(test)] extern crate test;
|
||||
|
||||
#[cfg(test)] #[phase(plugin, link)] extern crate std;
|
||||
|
@ -83,7 +83,6 @@ extern crate core;
|
||||
|
||||
#[cfg(test)] extern crate std;
|
||||
#[cfg(test)] extern crate test;
|
||||
#[cfg(test)] extern crate native;
|
||||
|
||||
pub use self::Nullable::*;
|
||||
|
||||
|
@ -33,7 +33,6 @@ extern crate core;
|
||||
|
||||
#[cfg(test)] #[phase(plugin, link)] extern crate std;
|
||||
#[cfg(test)] #[phase(plugin, link)] extern crate log;
|
||||
#[cfg(test)] extern crate native;
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
|
@ -30,7 +30,6 @@ extern crate collections;
|
||||
|
||||
#[cfg(test)] extern crate "rustrt" as realrustrt;
|
||||
#[cfg(test)] extern crate test;
|
||||
#[cfg(test)] extern crate native;
|
||||
|
||||
#[cfg(test)] #[phase(plugin, link)] extern crate std;
|
||||
|
||||
|
@ -65,14 +65,7 @@ pub unsafe fn report() {
|
||||
#[cfg(any(windows, target_os = "linux", target_os = "macos"))]
|
||||
unsafe fn get_task_guard_page() -> Option<uint> {
|
||||
let task: Option<*mut Task> = Local::try_unsafe_borrow();
|
||||
|
||||
task.map(|task| {
|
||||
let runtime = (*task).take_runtime();
|
||||
let guard = runtime.stack_guard();
|
||||
(*task).put_runtime(runtime);
|
||||
|
||||
guard.unwrap_or(0)
|
||||
})
|
||||
task.map(|task| (&*task).stack_guard().unwrap_or(0))
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
|
@ -740,8 +740,6 @@ impl Drop for Process {
|
||||
mod tests {
|
||||
#![allow(unused_imports)]
|
||||
|
||||
extern crate native;
|
||||
|
||||
use super::*;
|
||||
use prelude::*;
|
||||
use io::timer::*;
|
||||
|
@ -117,7 +117,6 @@
|
||||
|
||||
#![reexport_test_harness_main = "test_main"]
|
||||
|
||||
#[cfg(test)] extern crate green;
|
||||
#[cfg(test)] #[phase(plugin, link)] extern crate log;
|
||||
|
||||
extern crate alloc;
|
||||
|
@ -58,7 +58,7 @@ Several modules in `core` are clients of `rt`:
|
||||
|
||||
use failure;
|
||||
use rustrt;
|
||||
use startup;
|
||||
use os;
|
||||
|
||||
// Reexport some of our utilities which are expected by other crates.
|
||||
pub use self::util::{default_sched_threads, min_stack, running_on_valgrind};
|
||||
@ -66,9 +66,9 @@ pub use self::util::{default_sched_threads, min_stack, running_on_valgrind};
|
||||
// Reexport functionality from librustrt and other crates underneath the
|
||||
// standard library which work together to create the entire runtime.
|
||||
pub use alloc::heap;
|
||||
pub use rustrt::{task, local, mutex, exclusive, stack, args, rtio, thread};
|
||||
pub use rustrt::{task, local, mutex, exclusive, stack, args, thread};
|
||||
pub use rustrt::{Stdio, Stdout, Stderr, begin_unwind, begin_unwind_fmt};
|
||||
pub use rustrt::{bookkeeping, at_exit, unwind, DEFAULT_ERROR_CODE, Runtime};
|
||||
pub use rustrt::{at_exit, unwind, DEFAULT_ERROR_CODE};
|
||||
|
||||
// Simple backtrace functionality (to print on panic)
|
||||
pub mod backtrace;
|
||||
@ -95,7 +95,7 @@ static OS_DEFAULT_STACK_ESTIMATE: uint = 2 * (1 << 20);
|
||||
#[cfg(not(test))]
|
||||
#[lang = "start"]
|
||||
fn lang_start(main: *const u8, argc: int, argv: *const *const u8) -> int {
|
||||
use std::mem;
|
||||
use mem;
|
||||
start(argc, argv, proc() {
|
||||
let main: extern "Rust" fn() = unsafe { mem::transmute(main) };
|
||||
main();
|
||||
@ -147,8 +147,8 @@ pub fn start(argc: int, argv: *const *const u8, main: proc()) -> int {
|
||||
init(argc, argv);
|
||||
let mut exit_code = None;
|
||||
let mut main = Some(main);
|
||||
let mut task = task::new((my_stack_bottom, my_stack_top),
|
||||
rt::thread::main_guard_page());
|
||||
let mut task = Task::new(Some((my_stack_bottom, my_stack_top)),
|
||||
Some(rt::thread::main_guard_page()));
|
||||
task.name = Some(str::Slice("<main>"));
|
||||
drop(task.run(|| {
|
||||
unsafe {
|
||||
|
@ -21,7 +21,7 @@
|
||||
//! time.
|
||||
|
||||
use mem;
|
||||
use rt::bookkeeping;
|
||||
use rustrt::bookkeeping;
|
||||
use rt::mutex::StaticNativeMutex;
|
||||
use rt;
|
||||
use cell::UnsafeCell;
|
||||
|
@ -11,11 +11,7 @@
|
||||
//! Task creation
|
||||
//!
|
||||
//! An executing Rust program consists of a collection of tasks, each
|
||||
//! with their own stack and local state. A Rust task is typically
|
||||
//! backed by an operating system thread, making tasks 'just threads',
|
||||
//! but may also be implemented via other strategies as well
|
||||
//! (e.g. Rust comes with the [`green`](../../green/index.html)
|
||||
//! scheduling crate for creating tasks backed by green threads).
|
||||
//! with their own stack and local state.
|
||||
//!
|
||||
//! Tasks generally have their memory *isolated* from each other by
|
||||
//! virtue of Rust's owned types (which of course may only be owned by
|
||||
@ -36,13 +32,6 @@
|
||||
//! the main task panics the application will exit with a non-zero
|
||||
//! exit code.
|
||||
//!
|
||||
//! # Basic task scheduling
|
||||
//!
|
||||
//! By default, every task is created with the same "flavor" as the calling task.
|
||||
//! This flavor refers to the scheduling mode, with two possibilities currently
|
||||
//! being 1:1 and M:N modes. Green (M:N) tasks are cooperatively scheduled and
|
||||
//! native (1:1) tasks are scheduled by the OS kernel.
|
||||
//!
|
||||
//! ## Example
|
||||
//!
|
||||
//! ```rust
|
||||
@ -50,46 +39,6 @@
|
||||
//! println!("Hello, World!");
|
||||
//! })
|
||||
//! ```
|
||||
//!
|
||||
//! # Advanced task scheduling
|
||||
//!
|
||||
//! Task spawning can also be configured to use a particular scheduler, to
|
||||
//! redirect the new task's output, or to yield a `future` representing the
|
||||
//! task's final result. The configuration is established using the
|
||||
//! `TaskBuilder` API:
|
||||
//!
|
||||
//! ## Example
|
||||
//!
|
||||
//! ```rust
|
||||
//! extern crate green;
|
||||
//! extern crate native;
|
||||
//!
|
||||
//! use std::task::TaskBuilder;
|
||||
//! use green::{SchedPool, PoolConfig, GreenTaskBuilder};
|
||||
//! use native::NativeTaskBuilder;
|
||||
//!
|
||||
//! # fn main() {
|
||||
//! // Create a green scheduler pool with the default configuration
|
||||
//! let mut pool = SchedPool::new(PoolConfig::new());
|
||||
//!
|
||||
//! // Spawn a task in the green pool
|
||||
//! let mut fut_green = TaskBuilder::new().green(&mut pool).try_future(proc() {
|
||||
//! /* ... */
|
||||
//! });
|
||||
//!
|
||||
//! // Spawn a native task
|
||||
//! let mut fut_native = TaskBuilder::new().native().try_future(proc() {
|
||||
//! /* ... */
|
||||
//! });
|
||||
//!
|
||||
//! // Wait for both tasks to finish, recording their outcome
|
||||
//! let res_green = fut_green.unwrap();
|
||||
//! let res_native = fut_native.unwrap();
|
||||
//!
|
||||
//! // Shut down the green scheduler pool
|
||||
//! pool.shutdown();
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
#![unstable = "The task spawning model will be changed as part of runtime reform, and the module \
|
||||
will likely be renamed from `task` to `thread`."]
|
||||
@ -108,26 +57,6 @@ use str::{Str, SendStr, IntoMaybeOwned};
|
||||
use string::{String, ToString};
|
||||
use sync::Future;
|
||||
|
||||
/// A means of spawning a task
|
||||
pub trait Spawner {
|
||||
/// Spawn a task, given low-level task options.
|
||||
fn spawn(self, opts: task::TaskOpts, f: proc():Send);
|
||||
}
|
||||
|
||||
/// The default task spawner, which spawns siblings to the current task.
|
||||
pub struct SiblingSpawner;
|
||||
|
||||
impl Spawner for SiblingSpawner {
|
||||
fn spawn(self, opts: task::TaskOpts, f: proc():Send) {
|
||||
// bind tb to provide type annotation
|
||||
let tb: Option<Box<Task>> = Local::try_take();
|
||||
match tb {
|
||||
Some(t) => t.spawn_sibling(opts, f),
|
||||
None => panic!("need a local task to spawn a sibling task"),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// The task builder type.
|
||||
///
|
||||
/// Provides detailed control over the properties and behavior of new tasks.
|
||||
@ -139,7 +68,7 @@ impl Spawner for SiblingSpawner {
|
||||
// when you try to reuse the builder to spawn a new task. We'll just
|
||||
// sidestep that whole issue by making builders uncopyable and making
|
||||
// the run function move them in.
|
||||
pub struct TaskBuilder<S = SiblingSpawner> {
|
||||
pub struct TaskBuilder {
|
||||
// A name for the task-to-be, for identification in panic messages
|
||||
name: Option<SendStr>,
|
||||
// The size of the stack for the spawned task
|
||||
@ -148,88 +77,60 @@ pub struct TaskBuilder<S = SiblingSpawner> {
|
||||
stdout: Option<Box<Writer + Send>>,
|
||||
// Task-local stderr
|
||||
stderr: Option<Box<Writer + Send>>,
|
||||
// The mechanics of actually spawning the task (i.e.: green or native)
|
||||
spawner: S,
|
||||
// Optionally wrap the eventual task body
|
||||
gen_body: Option<proc(v: proc():Send):Send -> proc():Send>,
|
||||
nocopy: marker::NoCopy,
|
||||
}
|
||||
|
||||
impl TaskBuilder<SiblingSpawner> {
|
||||
impl TaskBuilder {
|
||||
/// Generate the base configuration for spawning a task, off of which more
|
||||
/// configuration methods can be chained.
|
||||
pub fn new() -> TaskBuilder<SiblingSpawner> {
|
||||
pub fn new() -> TaskBuilder {
|
||||
TaskBuilder {
|
||||
name: None,
|
||||
stack_size: None,
|
||||
stdout: None,
|
||||
stderr: None,
|
||||
spawner: SiblingSpawner,
|
||||
gen_body: None,
|
||||
nocopy: marker::NoCopy,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Spawner> TaskBuilder<S> {
|
||||
impl TaskBuilder {
|
||||
/// Name the task-to-be. Currently the name is used for identification
|
||||
/// only in panic messages.
|
||||
#[unstable = "IntoMaybeOwned will probably change."]
|
||||
pub fn named<T: IntoMaybeOwned<'static>>(mut self, name: T) -> TaskBuilder<S> {
|
||||
pub fn named<T: IntoMaybeOwned<'static>>(mut self, name: T) -> TaskBuilder {
|
||||
self.name = Some(name.into_maybe_owned());
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the size of the stack for the new task.
|
||||
pub fn stack_size(mut self, size: uint) -> TaskBuilder<S> {
|
||||
pub fn stack_size(mut self, size: uint) -> TaskBuilder {
|
||||
self.stack_size = Some(size);
|
||||
self
|
||||
}
|
||||
|
||||
/// Redirect task-local stdout.
|
||||
#[experimental = "May not want to make stdio overridable here."]
|
||||
pub fn stdout(mut self, stdout: Box<Writer + Send>) -> TaskBuilder<S> {
|
||||
pub fn stdout(mut self, stdout: Box<Writer + Send>) -> TaskBuilder {
|
||||
self.stdout = Some(stdout);
|
||||
self
|
||||
}
|
||||
|
||||
/// Redirect task-local stderr.
|
||||
#[experimental = "May not want to make stdio overridable here."]
|
||||
pub fn stderr(mut self, stderr: Box<Writer + Send>) -> TaskBuilder<S> {
|
||||
pub fn stderr(mut self, stderr: Box<Writer + Send>) -> TaskBuilder {
|
||||
self.stderr = Some(stderr);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the spawning mechanism for the task.
|
||||
///
|
||||
/// The `TaskBuilder` API configures a task to be spawned, but defers to the
|
||||
/// "spawner" to actually create and spawn the task. The `spawner` method
|
||||
/// should not be called directly by `TaskBuiler` clients. It is intended
|
||||
/// for use by downstream crates (like `native` and `green`) that implement
|
||||
/// tasks. These downstream crates then add extension methods to the
|
||||
/// builder, like `.native()` and `.green(pool)`, that actually set the
|
||||
/// spawner.
|
||||
pub fn spawner<T: Spawner>(self, spawner: T) -> TaskBuilder<T> {
|
||||
// repackage the entire TaskBuilder since its type is changing.
|
||||
let TaskBuilder {
|
||||
name, stack_size, stdout, stderr, spawner: _, gen_body, nocopy
|
||||
} = self;
|
||||
TaskBuilder {
|
||||
name: name,
|
||||
stack_size: stack_size,
|
||||
stdout: stdout,
|
||||
stderr: stderr,
|
||||
spawner: spawner,
|
||||
gen_body: gen_body,
|
||||
nocopy: nocopy,
|
||||
}
|
||||
}
|
||||
|
||||
// Where spawning actually happens (whether yielding a future or not)
|
||||
fn spawn_internal(self, f: proc():Send,
|
||||
on_exit: Option<proc(Result<(), Box<Any + Send>>):Send>) {
|
||||
let TaskBuilder {
|
||||
name, stack_size, stdout, stderr, spawner, mut gen_body, nocopy: _
|
||||
name, stack_size, stdout, stderr, mut gen_body, nocopy: _
|
||||
} = self;
|
||||
let f = match gen_body.take() {
|
||||
Some(gen) => gen(f),
|
||||
@ -348,11 +249,8 @@ pub fn name() -> Option<String> {
|
||||
/// Yield control to the task scheduler.
|
||||
#[unstable = "Name will change."]
|
||||
pub fn deschedule() {
|
||||
use rt::local::Local;
|
||||
|
||||
// FIXME(#7544): Optimize this, since we know we won't block.
|
||||
let task: Box<Task> = Local::take();
|
||||
task.yield_now();
|
||||
use rt::task::Task;
|
||||
Task::yield_now();
|
||||
}
|
||||
|
||||
/// True if the running task is currently panicking (e.g. will return `true` inside a
|
||||
|
@ -42,7 +42,6 @@
|
||||
//! ```
|
||||
//! use std::sync::Arc;
|
||||
//! use std::sync::atomic::{AtomicUint, SeqCst};
|
||||
//! use std::task::deschedule;
|
||||
//!
|
||||
//! fn main() {
|
||||
//! let spinlock = Arc::new(AtomicUint::new(1));
|
||||
@ -53,13 +52,7 @@
|
||||
//! });
|
||||
//!
|
||||
//! // Wait for the other task to release the lock
|
||||
//! while spinlock.load(SeqCst) != 0 {
|
||||
//! // Since tasks may not be preemptive (if they are green threads)
|
||||
//! // yield to the scheduler to let the other task run. Low level
|
||||
//! // concurrent code needs to take into account Rust's two threading
|
||||
//! // models.
|
||||
//! deschedule();
|
||||
//! }
|
||||
//! while spinlock.load(SeqCst) != 0 {}
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
|
@ -65,10 +65,6 @@
|
||||
//! the `try_send` method on a `SyncSender`, but no other operations are
|
||||
//! guaranteed to be safe.
|
||||
//!
|
||||
//! Additionally, channels can interoperate between runtimes. If one task in a
|
||||
//! program is running on libnative and another is running on libgreen, they can
|
||||
//! still communicate with one another using channels.
|
||||
//!
|
||||
//! # Example
|
||||
//!
|
||||
//! Simple usage:
|
||||
@ -328,13 +324,10 @@ pub use self::TrySendError::*;
|
||||
use self::Flavor::*;
|
||||
|
||||
use alloc::arc::Arc;
|
||||
use alloc::boxed::Box;
|
||||
use core::cell::Cell;
|
||||
use core::kinds::marker;
|
||||
use core::mem;
|
||||
use core::cell::UnsafeCell;
|
||||
use rustrt::local::Local;
|
||||
use rustrt::task::{Task, BlockedTask};
|
||||
use rustrt::task::BlockedTask;
|
||||
|
||||
pub use comm::select::{Select, Handle};
|
||||
|
||||
@ -345,21 +338,12 @@ macro_rules! test (
|
||||
|
||||
use std::prelude::*;
|
||||
|
||||
use native;
|
||||
use comm::*;
|
||||
use super::*;
|
||||
use super::super::*;
|
||||
use std::task;
|
||||
|
||||
fn f() $b
|
||||
|
||||
$(#[$a])* #[test] fn uv() { f() }
|
||||
$(#[$a])* #[test] fn native() {
|
||||
use native;
|
||||
let (tx, rx) = channel();
|
||||
spawn(proc() { tx.send(f()) });
|
||||
rx.recv();
|
||||
}
|
||||
$(#[$a])* #[test] fn f() { $b }
|
||||
}
|
||||
)
|
||||
)
|
||||
@ -370,16 +354,11 @@ mod shared;
|
||||
mod stream;
|
||||
mod sync;
|
||||
|
||||
// Use a power of 2 to allow LLVM to optimize to something that's not a
|
||||
// division, this is hit pretty regularly.
|
||||
static RESCHED_FREQ: int = 256;
|
||||
|
||||
/// The receiving-half of Rust's channel type. This half can only be owned by
|
||||
/// one task
|
||||
#[unstable]
|
||||
pub struct Receiver<T> {
|
||||
inner: UnsafeCell<Flavor<T>>,
|
||||
receives: Cell<uint>,
|
||||
// can't share in an arc
|
||||
_marker: marker::NoSync,
|
||||
}
|
||||
@ -397,7 +376,6 @@ pub struct Messages<'a, T:'a> {
|
||||
#[unstable]
|
||||
pub struct Sender<T> {
|
||||
inner: UnsafeCell<Flavor<T>>,
|
||||
sends: Cell<uint>,
|
||||
// can't share in an arc
|
||||
_marker: marker::NoSync,
|
||||
}
|
||||
@ -544,7 +522,6 @@ impl<T: Send> Sender<T> {
|
||||
fn new(inner: Flavor<T>) -> Sender<T> {
|
||||
Sender {
|
||||
inner: UnsafeCell::new(inner),
|
||||
sends: Cell::new(0),
|
||||
_marker: marker::NoSync,
|
||||
}
|
||||
}
|
||||
@ -608,21 +585,6 @@ impl<T: Send> Sender<T> {
|
||||
/// ```
|
||||
#[unstable = "this function may be renamed to send() in the future"]
|
||||
pub fn send_opt(&self, t: T) -> Result<(), T> {
|
||||
// In order to prevent starvation of other tasks in situations where
|
||||
// a task sends repeatedly without ever receiving, we occasionally
|
||||
// yield instead of doing a send immediately.
|
||||
//
|
||||
// Don't unconditionally attempt to yield because the TLS overhead can
|
||||
// be a bit much, and also use `try_take` instead of `take` because
|
||||
// there's no reason that this send shouldn't be usable off the
|
||||
// runtime.
|
||||
let cnt = self.sends.get() + 1;
|
||||
self.sends.set(cnt);
|
||||
if cnt % (RESCHED_FREQ as uint) == 0 {
|
||||
let task: Option<Box<Task>> = Local::try_take();
|
||||
task.map(|t| t.maybe_yield());
|
||||
}
|
||||
|
||||
let (new_inner, ret) = match *unsafe { self.inner() } {
|
||||
Oneshot(ref p) => {
|
||||
unsafe {
|
||||
@ -809,7 +771,7 @@ impl<T: Send> Drop for SyncSender<T> {
|
||||
|
||||
impl<T: Send> Receiver<T> {
|
||||
fn new(inner: Flavor<T>) -> Receiver<T> {
|
||||
Receiver { inner: UnsafeCell::new(inner), receives: Cell::new(0), _marker: marker::NoSync }
|
||||
Receiver { inner: UnsafeCell::new(inner), _marker: marker::NoSync }
|
||||
}
|
||||
|
||||
/// Blocks waiting for a value on this receiver
|
||||
@ -854,17 +816,6 @@ impl<T: Send> Receiver<T> {
|
||||
/// This function cannot panic.
|
||||
#[unstable = "the return type of this function may be altered"]
|
||||
pub fn try_recv(&self) -> Result<T, TryRecvError> {
|
||||
// If a thread is spinning in try_recv, we should take the opportunity
|
||||
// to reschedule things occasionally. See notes above in scheduling on
|
||||
// sends for why this doesn't always hit TLS, and also for why this uses
|
||||
// `try_take` instead of `take`.
|
||||
let cnt = self.receives.get() + 1;
|
||||
self.receives.set(cnt);
|
||||
if cnt % (RESCHED_FREQ as uint) == 0 {
|
||||
let task: Option<Box<Task>> = Local::try_take();
|
||||
task.map(|t| t.maybe_yield());
|
||||
}
|
||||
|
||||
loop {
|
||||
let new_port = match *unsafe { self.inner() } {
|
||||
Oneshot(ref p) => {
|
||||
|
@ -279,17 +279,6 @@ impl<T: Send> Packet<T> {
|
||||
// because the remote sender should finish their enqueue
|
||||
// operation "very quickly".
|
||||
//
|
||||
// Note that this yield loop does *not* attempt to do a green
|
||||
// yield (regardless of the context), but *always* performs an
|
||||
// OS-thread yield. The reasoning for this is that the pusher in
|
||||
// question which is causing the inconsistent state is
|
||||
// guaranteed to *not* be a blocked task (green tasks can't get
|
||||
// pre-empted), so it must be on a different OS thread. Also,
|
||||
// `try_recv` is normally a "guaranteed no rescheduling" context
|
||||
// in a green-thread situation. By yielding control of the
|
||||
// thread, we will hopefully allow time for the remote task on
|
||||
// the other OS thread to make progress.
|
||||
//
|
||||
// Avoiding this yield loop would require a different queue
|
||||
// abstraction which provides the guarantee that after M
|
||||
// pushes have succeeded, at least M pops will succeed. The
|
||||
|
@ -38,7 +38,6 @@ extern crate collections;
|
||||
extern crate rustrt;
|
||||
|
||||
#[cfg(test)] extern crate test;
|
||||
#[cfg(test)] extern crate native;
|
||||
#[cfg(test)] #[phase(plugin, link)] extern crate std;
|
||||
|
||||
pub use alloc::arc::{Arc, Weak};
|
||||
|
@ -1,41 +0,0 @@
|
||||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![no_start]
|
||||
|
||||
extern crate green;
|
||||
|
||||
use std::task::spawn;
|
||||
use std::os;
|
||||
use std::uint;
|
||||
|
||||
// Very simple spawn rate test. Spawn N tasks that do nothing and
|
||||
// return.
|
||||
|
||||
#[start]
|
||||
fn start(argc: int, argv: *const *const u8) -> int {
|
||||
green::start(argc, argv, green::basic::event_loop, main)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
||||
let args = os::args();
|
||||
let args = args.as_slice();
|
||||
let n = if args.len() == 2 {
|
||||
from_str::<uint>(args[1].as_slice()).unwrap()
|
||||
} else {
|
||||
100000
|
||||
};
|
||||
|
||||
for _ in range(0, n) {
|
||||
spawn(proc() {});
|
||||
}
|
||||
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// This is (hopefully) a quick test to get a good idea about spawning
|
||||
// performance in libgreen.
|
||||
|
||||
extern crate green;
|
||||
|
||||
#[start]
|
||||
fn start(argc: int, argv: *const *const u8) -> int {
|
||||
green::start(argc, argv, green::basic::event_loop, main)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
for _ in range(1u32, 100_000) {
|
||||
spawn(proc() {})
|
||||
}
|
||||
}
|
@ -3,7 +3,6 @@
|
||||
#![feature(globs)]
|
||||
#[phase(plugin, link)]
|
||||
extern crate "std" as std;
|
||||
extern crate "native" as rt;
|
||||
#[prelude_import]
|
||||
use std::prelude::*;
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
|
@ -1,21 +0,0 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// ignore-android (FIXME #11419)
|
||||
// error-pattern:explicit panic
|
||||
|
||||
extern crate native;
|
||||
|
||||
#[start]
|
||||
fn start(argc: int, argv: *const *const u8) -> int {
|
||||
native::start(argc, argv, proc() {
|
||||
panic!();
|
||||
})
|
||||
}
|
@ -11,11 +11,11 @@
|
||||
#![crate_name="boot"]
|
||||
#![crate_type="dylib"]
|
||||
|
||||
extern crate native;
|
||||
use std::rt;
|
||||
|
||||
#[no_mangle] // this needs to get called from C
|
||||
pub extern "C" fn foo(argc: int, argv: *const *const u8) -> int {
|
||||
native::start(argc, argv, proc() {
|
||||
rt::start(argc, argv, proc() {
|
||||
spawn(proc() {
|
||||
println!("hello");
|
||||
});
|
||||
|
@ -10,18 +10,11 @@
|
||||
|
||||
// no-pretty-expanded FIXME #15189
|
||||
// ignore-windows FIXME #13259
|
||||
extern crate native;
|
||||
|
||||
use std::os;
|
||||
use std::io::process::Command;
|
||||
use std::finally::Finally;
|
||||
use std::str;
|
||||
|
||||
#[start]
|
||||
fn start(argc: int, argv: *const *const u8) -> int {
|
||||
native::start(argc, argv, main)
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
fn foo() {
|
||||
let _v = vec![1i, 2, 3];
|
||||
|
@ -15,7 +15,6 @@
|
||||
|
||||
#[phase(plugin, link)]
|
||||
extern crate log;
|
||||
extern crate native;
|
||||
|
||||
use log::{set_logger, Logger, LogRecord};
|
||||
use std::fmt;
|
||||
@ -30,13 +29,6 @@ impl Logger for MyWriter {
|
||||
}
|
||||
}
|
||||
|
||||
#[start]
|
||||
fn start(argc: int, argv: *const *const u8) -> int {
|
||||
native::start(argc, argv, proc() {
|
||||
main();
|
||||
})
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let (tx, rx) = channel();
|
||||
let (mut r, w) = (ChanReader::new(rx), ChanWriter::new(tx));
|
||||
|
@ -8,17 +8,9 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
|
||||
extern crate native;
|
||||
|
||||
use std::io::timer;
|
||||
use std::time::Duration;
|
||||
|
||||
#[start]
|
||||
fn start(argc: int, argv: *const *const u8) -> int {
|
||||
native::start(argc, argv, main)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
timer::sleep(Duration::milliseconds(250));
|
||||
}
|
||||
|
@ -8,24 +8,10 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
|
||||
extern crate green;
|
||||
|
||||
static mut DROP: int = 0i;
|
||||
static mut DROP_S: int = 0i;
|
||||
static mut DROP_T: int = 0i;
|
||||
|
||||
#[start]
|
||||
fn start(argc: int, argv: *const *const u8) -> int {
|
||||
let ret = green::start(argc, argv, green::basic::event_loop, main);
|
||||
unsafe {
|
||||
assert_eq!(2, DROP);
|
||||
assert_eq!(1, DROP_S);
|
||||
assert_eq!(1, DROP_T);
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
struct S;
|
||||
impl Drop for S {
|
||||
fn drop(&mut self) {
|
||||
@ -48,7 +34,7 @@ impl Drop for T {
|
||||
}
|
||||
fn g(ref _t: T) {}
|
||||
|
||||
fn main() {
|
||||
fn do_test() {
|
||||
let s = S;
|
||||
f(s);
|
||||
unsafe {
|
||||
@ -59,3 +45,12 @@ fn main() {
|
||||
g(t);
|
||||
unsafe { assert_eq!(1, DROP_T); }
|
||||
}
|
||||
|
||||
fn main() {
|
||||
do_test();
|
||||
unsafe {
|
||||
assert_eq!(2, DROP);
|
||||
assert_eq!(1, DROP_S);
|
||||
assert_eq!(1, DROP_T);
|
||||
}
|
||||
}
|
||||
|
@ -8,12 +8,14 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
extern crate native;
|
||||
extern crate rustrt;
|
||||
|
||||
use std::io::process::{Command, ProcessOutput};
|
||||
use std::os;
|
||||
use std::str;
|
||||
use std::rt::unwind::try;
|
||||
use std::rt;
|
||||
|
||||
use rustrt::unwind::try;
|
||||
|
||||
local_data_key!(foo: int)
|
||||
|
||||
@ -36,7 +38,7 @@ fn start(argc: int, argv: *const *const u8) -> int {
|
||||
return 0
|
||||
}
|
||||
|
||||
native::start(argc, argv, main)
|
||||
rt::start(argc, argv, main)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
Loading…
Reference in New Issue
Block a user