librustc: Make C functions unsafe
This commit is contained in:
@@ -280,17 +280,23 @@ extern mod rusti {
|
|||||||
// I get link errors. This is a bug that needs investigated more.
|
// I get link errors. This is a bug that needs investigated more.
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub fn atomic_xchng_rel(dst: &mut int, src: int) -> int {
|
pub fn atomic_xchng_rel(dst: &mut int, src: int) -> int {
|
||||||
rusti::atomic_xchg_rel(dst, src)
|
unsafe {
|
||||||
|
rusti::atomic_xchg_rel(dst, src)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub fn atomic_add_acq(dst: &mut int, src: int) -> int {
|
pub fn atomic_add_acq(dst: &mut int, src: int) -> int {
|
||||||
rusti::atomic_xadd_acq(dst, src)
|
unsafe {
|
||||||
|
rusti::atomic_xadd_acq(dst, src)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub fn atomic_sub_rel(dst: &mut int, src: int) -> int {
|
pub fn atomic_sub_rel(dst: &mut int, src: int) -> int {
|
||||||
rusti::atomic_xsub_rel(dst, src)
|
unsafe {
|
||||||
|
rusti::atomic_xsub_rel(dst, src)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
|
|||||||
@@ -93,8 +93,10 @@ type rust_port_id = uint;
|
|||||||
type GlobalPtr = *libc::uintptr_t;
|
type GlobalPtr = *libc::uintptr_t;
|
||||||
|
|
||||||
fn compare_and_swap(address: &mut int, oldval: int, newval: int) -> bool {
|
fn compare_and_swap(address: &mut int, oldval: int, newval: int) -> bool {
|
||||||
let old = rusti::atomic_cxchg(address, oldval, newval);
|
unsafe {
|
||||||
old == oldval
|
let old = rusti::atomic_cxchg(address, oldval, newval);
|
||||||
|
old == oldval
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -201,10 +201,12 @@ impl ReprVisitor {
|
|||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn visit_ptr_inner(ptr: *c_void, inner: *TyDesc) -> bool {
|
fn visit_ptr_inner(ptr: *c_void, inner: *TyDesc) -> bool {
|
||||||
let mut u = ReprVisitor(ptr, self.writer);
|
unsafe {
|
||||||
let v = reflect::MovePtrAdaptor(move u);
|
let mut u = ReprVisitor(ptr, self.writer);
|
||||||
visit_tydesc(inner, (move v) as @TyVisitor);
|
let v = reflect::MovePtrAdaptor(move u);
|
||||||
true
|
visit_tydesc(inner, (move v) as @TyVisitor);
|
||||||
|
true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@@ -558,11 +560,13 @@ impl ReprVisitor : TyVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_repr<T>(writer: @Writer, object: &T) {
|
pub fn write_repr<T>(writer: @Writer, object: &T) {
|
||||||
let ptr = ptr::to_unsafe_ptr(object) as *c_void;
|
unsafe {
|
||||||
let tydesc = intrinsic::get_tydesc::<T>();
|
let ptr = ptr::to_unsafe_ptr(object) as *c_void;
|
||||||
let mut u = ReprVisitor(ptr, writer);
|
let tydesc = intrinsic::get_tydesc::<T>();
|
||||||
let v = reflect::MovePtrAdaptor(move u);
|
let mut u = ReprVisitor(ptr, writer);
|
||||||
visit_tydesc(tydesc, (move v) as @TyVisitor)
|
let v = reflect::MovePtrAdaptor(move u);
|
||||||
|
visit_tydesc(tydesc, (move v) as @TyVisitor)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
@@ -571,23 +571,29 @@ pub fn try<T:Owned>(f: fn~() -> T) -> Result<T,()> {
|
|||||||
pub fn yield() {
|
pub fn yield() {
|
||||||
//! Yield control to the task scheduler
|
//! Yield control to the task scheduler
|
||||||
|
|
||||||
let task_ = rt::rust_get_task();
|
unsafe {
|
||||||
let killed = rt::rust_task_yield(task_);
|
let task_ = rt::rust_get_task();
|
||||||
if killed && !failing() {
|
let killed = rt::rust_task_yield(task_);
|
||||||
fail ~"killed";
|
if killed && !failing() {
|
||||||
|
fail ~"killed";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn failing() -> bool {
|
pub fn failing() -> bool {
|
||||||
//! True if the running task has failed
|
//! True if the running task has failed
|
||||||
|
|
||||||
rt::rust_task_is_unwinding(rt::rust_get_task())
|
unsafe {
|
||||||
|
rt::rust_task_is_unwinding(rt::rust_get_task())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_task() -> Task {
|
pub fn get_task() -> Task {
|
||||||
//! Get a handle to the running task
|
//! Get a handle to the running task
|
||||||
|
|
||||||
TaskHandle(rt::get_task_id())
|
unsafe {
|
||||||
|
TaskHandle(rt::get_task_id())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -608,7 +614,11 @@ pub fn get_task() -> Task {
|
|||||||
pub unsafe fn unkillable<U>(f: fn() -> U) -> U {
|
pub unsafe fn unkillable<U>(f: fn() -> U) -> U {
|
||||||
struct AllowFailure {
|
struct AllowFailure {
|
||||||
t: *rust_task,
|
t: *rust_task,
|
||||||
drop { rt::rust_task_allow_kill(self.t); }
|
drop {
|
||||||
|
unsafe {
|
||||||
|
rt::rust_task_allow_kill(self.t);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn AllowFailure(t: *rust_task) -> AllowFailure{
|
fn AllowFailure(t: *rust_task) -> AllowFailure{
|
||||||
@@ -617,17 +627,23 @@ pub unsafe fn unkillable<U>(f: fn() -> U) -> U {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let t = rt::rust_get_task();
|
unsafe {
|
||||||
let _allow_failure = AllowFailure(t);
|
let t = rt::rust_get_task();
|
||||||
rt::rust_task_inhibit_kill(t);
|
let _allow_failure = AllowFailure(t);
|
||||||
f()
|
rt::rust_task_inhibit_kill(t);
|
||||||
|
f()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The inverse of unkillable. Only ever to be used nested in unkillable().
|
/// The inverse of unkillable. Only ever to be used nested in unkillable().
|
||||||
pub unsafe fn rekillable<U>(f: fn() -> U) -> U {
|
pub unsafe fn rekillable<U>(f: fn() -> U) -> U {
|
||||||
struct DisallowFailure {
|
struct DisallowFailure {
|
||||||
t: *rust_task,
|
t: *rust_task,
|
||||||
drop { rt::rust_task_inhibit_kill(self.t); }
|
drop {
|
||||||
|
unsafe {
|
||||||
|
rt::rust_task_inhibit_kill(self.t);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn DisallowFailure(t: *rust_task) -> DisallowFailure {
|
fn DisallowFailure(t: *rust_task) -> DisallowFailure {
|
||||||
@@ -636,10 +652,12 @@ pub unsafe fn rekillable<U>(f: fn() -> U) -> U {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let t = rt::rust_get_task();
|
unsafe {
|
||||||
let _allow_failure = DisallowFailure(t);
|
let t = rt::rust_get_task();
|
||||||
rt::rust_task_allow_kill(t);
|
let _allow_failure = DisallowFailure(t);
|
||||||
f()
|
rt::rust_task_allow_kill(t);
|
||||||
|
f()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -650,8 +668,10 @@ pub unsafe fn atomically<U>(f: fn() -> U) -> U {
|
|||||||
struct DeferInterrupts {
|
struct DeferInterrupts {
|
||||||
t: *rust_task,
|
t: *rust_task,
|
||||||
drop {
|
drop {
|
||||||
rt::rust_task_allow_yield(self.t);
|
unsafe {
|
||||||
rt::rust_task_allow_kill(self.t);
|
rt::rust_task_allow_yield(self.t);
|
||||||
|
rt::rust_task_allow_kill(self.t);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -661,11 +681,13 @@ pub unsafe fn atomically<U>(f: fn() -> U) -> U {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let t = rt::rust_get_task();
|
unsafe {
|
||||||
let _interrupts = DeferInterrupts(t);
|
let t = rt::rust_get_task();
|
||||||
rt::rust_task_inhibit_kill(t);
|
let _interrupts = DeferInterrupts(t);
|
||||||
rt::rust_task_inhibit_yield(t);
|
rt::rust_task_inhibit_kill(t);
|
||||||
f()
|
rt::rust_task_inhibit_yield(t);
|
||||||
|
f()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test] #[should_fail] #[ignore(cfg(windows))]
|
#[test] #[should_fail] #[ignore(cfg(windows))]
|
||||||
@@ -908,18 +930,22 @@ fn test_spawn_sched() {
|
|||||||
let ch = oldcomm::Chan(&po);
|
let ch = oldcomm::Chan(&po);
|
||||||
|
|
||||||
fn f(i: int, ch: oldcomm::Chan<()>) {
|
fn f(i: int, ch: oldcomm::Chan<()>) {
|
||||||
let parent_sched_id = rt::rust_get_sched_id();
|
unsafe {
|
||||||
|
let parent_sched_id = rt::rust_get_sched_id();
|
||||||
|
|
||||||
do spawn_sched(SingleThreaded) {
|
do spawn_sched(SingleThreaded) {
|
||||||
let child_sched_id = rt::rust_get_sched_id();
|
unsafe {
|
||||||
assert parent_sched_id != child_sched_id;
|
let child_sched_id = rt::rust_get_sched_id();
|
||||||
|
assert parent_sched_id != child_sched_id;
|
||||||
|
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
oldcomm::send(ch, ());
|
oldcomm::send(ch, ());
|
||||||
} else {
|
} else {
|
||||||
f(i - 1, ch);
|
f(i - 1, ch);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
f(10, ch);
|
f(10, ch);
|
||||||
@@ -932,13 +958,17 @@ fn test_spawn_sched_childs_on_same_sched() {
|
|||||||
let ch = oldcomm::Chan(&po);
|
let ch = oldcomm::Chan(&po);
|
||||||
|
|
||||||
do spawn_sched(SingleThreaded) {
|
do spawn_sched(SingleThreaded) {
|
||||||
let parent_sched_id = rt::rust_get_sched_id();
|
unsafe {
|
||||||
do spawn {
|
let parent_sched_id = rt::rust_get_sched_id();
|
||||||
let child_sched_id = rt::rust_get_sched_id();
|
do spawn {
|
||||||
// This should be on the same scheduler
|
unsafe {
|
||||||
assert parent_sched_id == child_sched_id;
|
let child_sched_id = rt::rust_get_sched_id();
|
||||||
oldcomm::send(ch, ());
|
// This should be on the same scheduler
|
||||||
};
|
assert parent_sched_id == child_sched_id;
|
||||||
|
oldcomm::send(ch, ());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
oldcomm::recv(po);
|
oldcomm::recv(po);
|
||||||
@@ -1185,10 +1215,12 @@ fn test_sched_thread_per_core() {
|
|||||||
let (port, chan) = pipes::stream();
|
let (port, chan) = pipes::stream();
|
||||||
|
|
||||||
do spawn_sched(ThreadPerCore) |move chan| {
|
do spawn_sched(ThreadPerCore) |move chan| {
|
||||||
let cores = rt::rust_num_threads();
|
unsafe {
|
||||||
let reported_threads = rt::rust_sched_threads();
|
let cores = rt::rust_num_threads();
|
||||||
assert(cores as uint == reported_threads as uint);
|
let reported_threads = rt::rust_sched_threads();
|
||||||
chan.send(());
|
assert(cores as uint == reported_threads as uint);
|
||||||
|
chan.send(());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
port.recv();
|
port.recv();
|
||||||
@@ -1199,22 +1231,24 @@ fn test_spawn_thread_on_demand() {
|
|||||||
let (port, chan) = pipes::stream();
|
let (port, chan) = pipes::stream();
|
||||||
|
|
||||||
do spawn_sched(ManualThreads(2)) |move chan| {
|
do spawn_sched(ManualThreads(2)) |move chan| {
|
||||||
let max_threads = rt::rust_sched_threads();
|
unsafe {
|
||||||
assert(max_threads as int == 2);
|
let max_threads = rt::rust_sched_threads();
|
||||||
let running_threads = rt::rust_sched_current_nonlazy_threads();
|
assert(max_threads as int == 2);
|
||||||
assert(running_threads as int == 1);
|
let running_threads = rt::rust_sched_current_nonlazy_threads();
|
||||||
|
assert(running_threads as int == 1);
|
||||||
|
|
||||||
let (port2, chan2) = pipes::stream();
|
let (port2, chan2) = pipes::stream();
|
||||||
|
|
||||||
do spawn() |move chan2| {
|
do spawn() |move chan2| {
|
||||||
chan2.send(());
|
chan2.send(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let running_threads2 = rt::rust_sched_current_nonlazy_threads();
|
||||||
|
assert(running_threads2 as int == 2);
|
||||||
|
|
||||||
|
port2.recv();
|
||||||
|
chan.send(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let running_threads2 = rt::rust_sched_current_nonlazy_threads();
|
|
||||||
assert(running_threads2 as int == 2);
|
|
||||||
|
|
||||||
port2.recv();
|
|
||||||
chan.send(());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
port.recv();
|
port.recv();
|
||||||
|
|||||||
@@ -308,25 +308,28 @@ struct TCB {
|
|||||||
notifier: Option<AutoNotify>,
|
notifier: Option<AutoNotify>,
|
||||||
// Runs on task exit.
|
// Runs on task exit.
|
||||||
drop {
|
drop {
|
||||||
// If we are failing, the whole taskgroup needs to die.
|
unsafe {
|
||||||
if rt::rust_task_is_unwinding(self.me) {
|
// If we are failing, the whole taskgroup needs to die.
|
||||||
self.notifier.iter(|x| { x.failed = true; });
|
if rt::rust_task_is_unwinding(self.me) {
|
||||||
// Take everybody down with us.
|
self.notifier.iter(|x| { x.failed = true; });
|
||||||
do access_group(&self.tasks) |tg| {
|
// Take everybody down with us.
|
||||||
kill_taskgroup(tg, self.me, self.is_main);
|
do access_group(&self.tasks) |tg| {
|
||||||
}
|
kill_taskgroup(tg, self.me, self.is_main);
|
||||||
} else {
|
}
|
||||||
// Remove ourselves from the group(s).
|
} else {
|
||||||
do access_group(&self.tasks) |tg| {
|
// Remove ourselves from the group(s).
|
||||||
leave_taskgroup(tg, self.me, true);
|
do access_group(&self.tasks) |tg| {
|
||||||
|
leave_taskgroup(tg, self.me, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
// It doesn't matter whether this happens before or after dealing
|
||||||
|
// with our own taskgroup, so long as both happen before we die.
|
||||||
|
// We remove ourself from every ancestor we can, so no cleanup; no
|
||||||
|
// break.
|
||||||
|
for each_ancestor(&mut self.ancestors, None) |ancestor_group| {
|
||||||
|
leave_taskgroup(ancestor_group, self.me, false);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
// It doesn't matter whether this happens before or after dealing with
|
|
||||||
// our own taskgroup, so long as both happen before we die. We need to
|
|
||||||
// remove ourself from every ancestor we can, so no cleanup; no break.
|
|
||||||
for each_ancestor(&mut self.ancestors, None) |ancestor_group| {
|
|
||||||
leave_taskgroup(ancestor_group, self.me, false);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -391,38 +394,41 @@ fn leave_taskgroup(state: TaskGroupInner, me: *rust_task,
|
|||||||
|
|
||||||
// NB: Runs in destructor/post-exit context. Can't 'fail'.
|
// NB: Runs in destructor/post-exit context. Can't 'fail'.
|
||||||
fn kill_taskgroup(state: TaskGroupInner, me: *rust_task, is_main: bool) {
|
fn kill_taskgroup(state: TaskGroupInner, me: *rust_task, is_main: bool) {
|
||||||
// NB: We could do the killing iteration outside of the group arc, by
|
unsafe {
|
||||||
// having "let mut newstate" here, swapping inside, and iterating after.
|
// NB: We could do the killing iteration outside of the group arc, by
|
||||||
// But that would let other exiting tasks fall-through and exit while we
|
// having "let mut newstate" here, swapping inside, and iterating
|
||||||
// were trying to kill them, causing potential use-after-free. A task's
|
// after. But that would let other exiting tasks fall-through and exit
|
||||||
// presence in the arc guarantees it's alive only while we hold the lock,
|
// while we were trying to kill them, causing potential
|
||||||
// so if we're failing, all concurrently exiting tasks must wait for us.
|
// use-after-free. A task's presence in the arc guarantees it's alive
|
||||||
// To do it differently, we'd have to use the runtime's task refcounting,
|
// only while we hold the lock, so if we're failing, all concurrently
|
||||||
// but that could leave task structs around long after their task exited.
|
// exiting tasks must wait for us. To do it differently, we'd have to
|
||||||
let newstate = util::replace(state, None);
|
// use the runtime's task refcounting, but that could leave task
|
||||||
// Might already be None, if Somebody is failing simultaneously.
|
// structs around long after their task exited.
|
||||||
// That's ok; only one task needs to do the dirty work. (Might also
|
let newstate = util::replace(state, None);
|
||||||
// see 'None' if Somebody already failed and we got a kill signal.)
|
// Might already be None, if Somebody is failing simultaneously.
|
||||||
if newstate.is_some() {
|
// That's ok; only one task needs to do the dirty work. (Might also
|
||||||
let group = option::unwrap(move newstate);
|
// see 'None' if Somebody already failed and we got a kill signal.)
|
||||||
for taskset_each(&group.members) |sibling| {
|
if newstate.is_some() {
|
||||||
// Skip self - killing ourself won't do much good.
|
let group = option::unwrap(move newstate);
|
||||||
if sibling != me {
|
for taskset_each(&group.members) |sibling| {
|
||||||
rt::rust_task_kill_other(sibling);
|
// Skip self - killing ourself won't do much good.
|
||||||
|
if sibling != me {
|
||||||
|
rt::rust_task_kill_other(sibling);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
for taskset_each(&group.descendants) |child| {
|
||||||
|
assert child != me;
|
||||||
|
rt::rust_task_kill_other(child);
|
||||||
|
}
|
||||||
|
// Only one task should ever do this.
|
||||||
|
if is_main {
|
||||||
|
rt::rust_task_kill_all(me);
|
||||||
|
}
|
||||||
|
// Do NOT restore state to Some(..)! It stays None to indicate
|
||||||
|
// that the whole taskgroup is failing, to forbid new spawns.
|
||||||
}
|
}
|
||||||
for taskset_each(&group.descendants) |child| {
|
// (note: multiple tasks may reach this point)
|
||||||
assert child != me;
|
|
||||||
rt::rust_task_kill_other(child);
|
|
||||||
}
|
|
||||||
// Only one task should ever do this.
|
|
||||||
if is_main {
|
|
||||||
rt::rust_task_kill_all(me);
|
|
||||||
}
|
|
||||||
// Do NOT restore state to Some(..)! It stays None to indicate
|
|
||||||
// that the whole taskgroup is failing, to forbid new spawns.
|
|
||||||
}
|
}
|
||||||
// (note: multiple tasks may reach this point)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME (#2912): Work around core-vs-coretest function duplication. Can't use
|
// FIXME (#2912): Work around core-vs-coretest function duplication. Can't use
|
||||||
@@ -434,68 +440,72 @@ macro_rules! taskgroup_key (
|
|||||||
|
|
||||||
fn gen_child_taskgroup(linked: bool, supervised: bool)
|
fn gen_child_taskgroup(linked: bool, supervised: bool)
|
||||||
-> (TaskGroupArc, AncestorList, bool) {
|
-> (TaskGroupArc, AncestorList, bool) {
|
||||||
let spawner = rt::rust_get_task();
|
unsafe {
|
||||||
/*######################################################################*
|
let spawner = rt::rust_get_task();
|
||||||
* Step 1. Get spawner's taskgroup info.
|
/*##################################################################*
|
||||||
*######################################################################*/
|
* Step 1. Get spawner's taskgroup info.
|
||||||
let spawner_group = match unsafe { local_get(spawner,
|
*##################################################################*/
|
||||||
taskgroup_key!()) } {
|
let spawner_group = match local_get(spawner, taskgroup_key!()) {
|
||||||
None => {
|
None => {
|
||||||
// Main task, doing first spawn ever. Lazily initialise here.
|
// Main task, doing first spawn ever. Lazily initialise here.
|
||||||
let mut members = new_taskset();
|
let mut members = new_taskset();
|
||||||
taskset_insert(&mut members, spawner);
|
taskset_insert(&mut members, spawner);
|
||||||
let tasks =
|
let tasks =
|
||||||
private::exclusive(Some({ mut members: move members,
|
private::exclusive(Some({
|
||||||
mut descendants: new_taskset() }));
|
mut members: move members,
|
||||||
// Main task/group has no ancestors, no notifier, etc.
|
mut descendants: new_taskset()
|
||||||
let group =
|
}));
|
||||||
@TCB(spawner, move tasks, AncestorList(None), true, None);
|
// Main task/group has no ancestors, no notifier, etc.
|
||||||
unsafe {
|
let group =
|
||||||
|
@TCB(spawner, move tasks, AncestorList(None), true, None);
|
||||||
local_set(spawner, taskgroup_key!(), group);
|
local_set(spawner, taskgroup_key!(), group);
|
||||||
|
group
|
||||||
}
|
}
|
||||||
group
|
Some(group) => group
|
||||||
}
|
|
||||||
Some(group) => group
|
|
||||||
};
|
|
||||||
/*######################################################################*
|
|
||||||
* Step 2. Process spawn options for child.
|
|
||||||
*######################################################################*/
|
|
||||||
return if linked {
|
|
||||||
// Child is in the same group as spawner.
|
|
||||||
let g = spawner_group.tasks.clone();
|
|
||||||
// Child's ancestors are spawner's ancestors.
|
|
||||||
let a = share_ancestors(&mut spawner_group.ancestors);
|
|
||||||
// Propagate main-ness.
|
|
||||||
(move g, move a, spawner_group.is_main)
|
|
||||||
} else {
|
|
||||||
// Child is in a separate group from spawner.
|
|
||||||
let g = private::exclusive(Some({ mut members: new_taskset(),
|
|
||||||
mut descendants: new_taskset() }));
|
|
||||||
let a = if supervised {
|
|
||||||
// Child's ancestors start with the spawner.
|
|
||||||
let old_ancestors = share_ancestors(&mut spawner_group.ancestors);
|
|
||||||
// FIXME(#3068) - The generation counter is only used for a debug
|
|
||||||
// assertion, but initialising it requires locking a mutex. Hence
|
|
||||||
// it should be enabled only in debug builds.
|
|
||||||
let new_generation =
|
|
||||||
match *old_ancestors {
|
|
||||||
Some(ref arc) => {
|
|
||||||
access_ancestors(arc, |a| a.generation+1)
|
|
||||||
}
|
|
||||||
None => 0 // the actual value doesn't really matter.
|
|
||||||
};
|
|
||||||
assert new_generation < uint::max_value;
|
|
||||||
// Build a new node in the ancestor list.
|
|
||||||
AncestorList(Some(private::exclusive(
|
|
||||||
{ generation: new_generation,
|
|
||||||
mut parent_group: Some(spawner_group.tasks.clone()),
|
|
||||||
mut ancestors: move old_ancestors })))
|
|
||||||
} else {
|
|
||||||
// Child has no ancestors.
|
|
||||||
AncestorList(None)
|
|
||||||
};
|
};
|
||||||
(move g, move a, false)
|
/*##################################################################*
|
||||||
};
|
* Step 2. Process spawn options for child.
|
||||||
|
*##################################################################*/
|
||||||
|
return if linked {
|
||||||
|
// Child is in the same group as spawner.
|
||||||
|
let g = spawner_group.tasks.clone();
|
||||||
|
// Child's ancestors are spawner's ancestors.
|
||||||
|
let a = share_ancestors(&mut spawner_group.ancestors);
|
||||||
|
// Propagate main-ness.
|
||||||
|
(move g, move a, spawner_group.is_main)
|
||||||
|
} else {
|
||||||
|
// Child is in a separate group from spawner.
|
||||||
|
let g = private::exclusive(Some({
|
||||||
|
mut members: new_taskset(),
|
||||||
|
mut descendants: new_taskset()
|
||||||
|
}));
|
||||||
|
let a = if supervised {
|
||||||
|
// Child's ancestors start with the spawner.
|
||||||
|
let old_ancestors =
|
||||||
|
share_ancestors(&mut spawner_group.ancestors);
|
||||||
|
// FIXME(#3068) - The generation counter is only used for a
|
||||||
|
// debug assertion, but initialising it requires locking a
|
||||||
|
// mutex. Hence it should be enabled only in debug builds.
|
||||||
|
let new_generation =
|
||||||
|
match *old_ancestors {
|
||||||
|
Some(ref arc) => {
|
||||||
|
access_ancestors(arc, |a| a.generation+1)
|
||||||
|
}
|
||||||
|
None => 0 // the actual value doesn't really matter.
|
||||||
|
};
|
||||||
|
assert new_generation < uint::max_value;
|
||||||
|
// Build a new node in the ancestor list.
|
||||||
|
AncestorList(Some(private::exclusive(
|
||||||
|
{ generation: new_generation,
|
||||||
|
mut parent_group: Some(spawner_group.tasks.clone()),
|
||||||
|
mut ancestors: move old_ancestors })))
|
||||||
|
} else {
|
||||||
|
// Child has no ancestors.
|
||||||
|
AncestorList(None)
|
||||||
|
};
|
||||||
|
(move g, move a, false)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
fn share_ancestors(ancestors: &mut AncestorList) -> AncestorList {
|
fn share_ancestors(ancestors: &mut AncestorList) -> AncestorList {
|
||||||
// Appease the borrow-checker. Really this wants to be written as:
|
// Appease the borrow-checker. Really this wants to be written as:
|
||||||
@@ -632,31 +642,33 @@ pub fn spawn_raw(opts: TaskOpts, f: fn~()) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn new_task_in_new_sched(opts: SchedOpts) -> *rust_task {
|
fn new_task_in_new_sched(opts: SchedOpts) -> *rust_task {
|
||||||
if opts.foreign_stack_size != None {
|
unsafe {
|
||||||
fail ~"foreign_stack_size scheduler option unimplemented";
|
if opts.foreign_stack_size != None {
|
||||||
}
|
fail ~"foreign_stack_size scheduler option unimplemented";
|
||||||
|
|
||||||
let num_threads = match opts.mode {
|
|
||||||
SingleThreaded => 1u,
|
|
||||||
ThreadPerCore => rt::rust_num_threads(),
|
|
||||||
ThreadPerTask => {
|
|
||||||
fail ~"ThreadPerTask scheduling mode unimplemented"
|
|
||||||
}
|
|
||||||
ManualThreads(threads) => {
|
|
||||||
if threads == 0u {
|
|
||||||
fail ~"can not create a scheduler with no threads";
|
|
||||||
}
|
}
|
||||||
threads
|
|
||||||
}
|
|
||||||
PlatformThread => 0u /* Won't be used */
|
|
||||||
};
|
|
||||||
|
|
||||||
let sched_id = if opts.mode != PlatformThread {
|
let num_threads = match opts.mode {
|
||||||
rt::rust_new_sched(num_threads)
|
SingleThreaded => 1u,
|
||||||
} else {
|
ThreadPerCore => rt::rust_num_threads(),
|
||||||
rt::rust_osmain_sched_id()
|
ThreadPerTask => {
|
||||||
};
|
fail ~"ThreadPerTask scheduling mode unimplemented"
|
||||||
rt::rust_new_task_in_sched(sched_id)
|
}
|
||||||
|
ManualThreads(threads) => {
|
||||||
|
if threads == 0u {
|
||||||
|
fail ~"can not create a scheduler with no threads";
|
||||||
|
}
|
||||||
|
threads
|
||||||
|
}
|
||||||
|
PlatformThread => 0u /* Won't be used */
|
||||||
|
};
|
||||||
|
|
||||||
|
let sched_id = if opts.mode != PlatformThread {
|
||||||
|
rt::rust_new_sched(num_threads)
|
||||||
|
} else {
|
||||||
|
rt::rust_osmain_sched_id()
|
||||||
|
};
|
||||||
|
rt::rust_new_task_in_sched(sched_id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,9 @@ mod intrinsic {
|
|||||||
// FIXME (#3727): remove this when the interface has settled and the
|
// FIXME (#3727): remove this when the interface has settled and the
|
||||||
// version in sys is no longer present.
|
// version in sys is no longer present.
|
||||||
pub fn get_tydesc<T>() -> *TyDesc {
|
pub fn get_tydesc<T>() -> *TyDesc {
|
||||||
rusti::get_tydesc::<T>() as *TyDesc
|
unsafe {
|
||||||
|
rusti::get_tydesc::<T>() as *TyDesc
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum TyDesc = {
|
pub enum TyDesc = {
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ use syntax::ast::{type_value_ns, ty_param_bound, unnamed_field};
|
|||||||
use syntax::ast::{variant, view_item, view_item_export, view_item_import};
|
use syntax::ast::{variant, view_item, view_item_export, view_item_import};
|
||||||
use syntax::ast::{view_item_use, view_path_glob, view_path_list};
|
use syntax::ast::{view_item_use, view_path_glob, view_path_list};
|
||||||
use syntax::ast::{view_path_simple, visibility, anonymous, named, not};
|
use syntax::ast::{view_path_simple, visibility, anonymous, named, not};
|
||||||
|
use syntax::ast::{unsafe_fn};
|
||||||
use syntax::ast_util::{def_id_of_def, dummy_sp, local_def};
|
use syntax::ast_util::{def_id_of_def, dummy_sp, local_def};
|
||||||
use syntax::ast_util::{path_to_ident, walk_pat, trait_method_to_ty_method};
|
use syntax::ast_util::{path_to_ident, walk_pat, trait_method_to_ty_method};
|
||||||
use syntax::ast_util::{Privacy, Public, Private, visibility_to_privacy};
|
use syntax::ast_util::{Privacy, Public, Private, visibility_to_privacy};
|
||||||
@@ -1643,8 +1644,8 @@ impl Resolver {
|
|||||||
foreign_item.span);
|
foreign_item.span);
|
||||||
|
|
||||||
match /*bad*/copy foreign_item.node {
|
match /*bad*/copy foreign_item.node {
|
||||||
foreign_item_fn(_, purity, type_parameters) => {
|
foreign_item_fn(_, _, type_parameters) => {
|
||||||
let def = def_fn(local_def(foreign_item.id), purity);
|
let def = def_fn(local_def(foreign_item.id), unsafe_fn);
|
||||||
(*name_bindings).define_value(Public, def, foreign_item.span);
|
(*name_bindings).define_value(Public, def, foreign_item.span);
|
||||||
|
|
||||||
do self.with_type_parameter_rib
|
do self.with_type_parameter_rib
|
||||||
|
|||||||
@@ -3342,7 +3342,7 @@ fn check_intrinsic_type(ccx: @crate_ctxt, it: @ast::foreign_item) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
let fty = ty::mk_fn(tcx, FnTyBase {
|
let fty = ty::mk_fn(tcx, FnTyBase {
|
||||||
meta: FnMeta {purity: ast::impure_fn,
|
meta: FnMeta {purity: ast::unsafe_fn,
|
||||||
proto: ast::ProtoBare,
|
proto: ast::ProtoBare,
|
||||||
onceness: ast::Many,
|
onceness: ast::Many,
|
||||||
region: ty::re_static,
|
region: ty::re_static,
|
||||||
|
|||||||
@@ -889,9 +889,8 @@ fn ty_of_item(ccx: @crate_ctxt, it: @ast::item)
|
|||||||
fn ty_of_foreign_item(ccx: @crate_ctxt, it: @ast::foreign_item)
|
fn ty_of_foreign_item(ccx: @crate_ctxt, it: @ast::foreign_item)
|
||||||
-> ty::ty_param_bounds_and_ty {
|
-> ty::ty_param_bounds_and_ty {
|
||||||
match /*bad*/copy it.node {
|
match /*bad*/copy it.node {
|
||||||
ast::foreign_item_fn(fn_decl, purity, params) => {
|
ast::foreign_item_fn(fn_decl, _, params) => {
|
||||||
return ty_of_foreign_fn_decl(ccx, fn_decl, purity, params,
|
return ty_of_foreign_fn_decl(ccx, fn_decl, params, local_def(it.id));
|
||||||
local_def(it.id));
|
|
||||||
}
|
}
|
||||||
ast::foreign_item_const(t) => {
|
ast::foreign_item_const(t) => {
|
||||||
let rb = in_binding_rscope(empty_rscope);
|
let rb = in_binding_rscope(empty_rscope);
|
||||||
@@ -962,7 +961,6 @@ fn ty_param_bounds(ccx: @crate_ctxt,
|
|||||||
|
|
||||||
fn ty_of_foreign_fn_decl(ccx: @crate_ctxt,
|
fn ty_of_foreign_fn_decl(ccx: @crate_ctxt,
|
||||||
decl: ast::fn_decl,
|
decl: ast::fn_decl,
|
||||||
purity: ast::purity,
|
|
||||||
+ty_params: ~[ast::ty_param],
|
+ty_params: ~[ast::ty_param],
|
||||||
def_id: ast::def_id) -> ty::ty_param_bounds_and_ty {
|
def_id: ast::def_id) -> ty::ty_param_bounds_and_ty {
|
||||||
let bounds = ty_param_bounds(ccx, ty_params);
|
let bounds = ty_param_bounds(ccx, ty_params);
|
||||||
@@ -971,7 +969,7 @@ fn ty_of_foreign_fn_decl(ccx: @crate_ctxt,
|
|||||||
let output_ty = ast_ty_to_ty(ccx, rb, decl.output);
|
let output_ty = ast_ty_to_ty(ccx, rb, decl.output);
|
||||||
|
|
||||||
let t_fn = ty::mk_fn(ccx.tcx, FnTyBase {
|
let t_fn = ty::mk_fn(ccx.tcx, FnTyBase {
|
||||||
meta: FnMeta {purity: purity,
|
meta: FnMeta {purity: ast::unsafe_fn,
|
||||||
onceness: ast::Many,
|
onceness: ast::Many,
|
||||||
proto: ast::ProtoBare,
|
proto: ast::ProtoBare,
|
||||||
bounds: @~[],
|
bounds: @~[],
|
||||||
|
|||||||
@@ -254,9 +254,13 @@ impl &Arena {
|
|||||||
// The external interface
|
// The external interface
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn alloc<T>(op: fn() -> T) -> &self/T {
|
fn alloc<T>(op: fn() -> T) -> &self/T {
|
||||||
if !rusti::needs_drop::<T>() {
|
unsafe {
|
||||||
self.alloc_pod(op)
|
if !rusti::needs_drop::<T>() {
|
||||||
} else { self.alloc_nonpod(op) }
|
self.alloc_pod(op)
|
||||||
|
} else {
|
||||||
|
self.alloc_nonpod(op)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,5 +31,7 @@ extern mod rusti {
|
|||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn atomic_xchg(dst: &mut int, src: int) -> int {
|
fn atomic_xchg(dst: &mut int, src: int) -> int {
|
||||||
rusti::atomic_xchg(dst, src)
|
unsafe {
|
||||||
|
rusti::atomic_xchg(dst, src)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,8 +21,10 @@ extern mod rustrt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn fact(n: uint) -> uint {
|
fn fact(n: uint) -> uint {
|
||||||
debug!("n = %?", n);
|
unsafe {
|
||||||
rustrt::rust_dbg_call(cb, n)
|
debug!("n = %?", n);
|
||||||
|
rustrt::rust_dbg_call(cb, n)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
|
extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
|
||||||
|
|||||||
@@ -30,7 +30,9 @@ pub enum port<T: Owned> {
|
|||||||
|
|
||||||
/// Constructs a port
|
/// Constructs a port
|
||||||
pub fn port<T: Owned>() -> port<T> {
|
pub fn port<T: Owned>() -> port<T> {
|
||||||
port_t(@port_ptr(rustrt::new_port(sys::size_of::<T>() as size_t)))
|
unsafe {
|
||||||
|
port_t(@port_ptr(rustrt::new_port(sys::size_of::<T>() as size_t)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct port_ptr<T:Owned> {
|
struct port_ptr<T:Owned> {
|
||||||
@@ -75,21 +77,23 @@ pub fn recv<T: Owned>(p: port<T>) -> T { recv_((**p).po) }
|
|||||||
|
|
||||||
/// Receive on a raw port pointer
|
/// Receive on a raw port pointer
|
||||||
pub fn recv_<T: Owned>(p: *rust_port) -> T {
|
pub fn recv_<T: Owned>(p: *rust_port) -> T {
|
||||||
let yield = 0;
|
unsafe {
|
||||||
let yieldp = ptr::addr_of(&yield);
|
let yield = 0;
|
||||||
let mut res;
|
let yieldp = ptr::addr_of(&yield);
|
||||||
res = rusti::init::<T>();
|
let mut res;
|
||||||
rustrt::port_recv(ptr::addr_of(&res) as *uint, p, yieldp);
|
res = rusti::init::<T>();
|
||||||
|
rustrt::port_recv(ptr::addr_of(&res) as *uint, p, yieldp);
|
||||||
|
|
||||||
if yield != 0 {
|
if yield != 0 {
|
||||||
// Data isn't available yet, so res has not been initialized.
|
// Data isn't available yet, so res has not been initialized.
|
||||||
task::yield();
|
task::yield();
|
||||||
} else {
|
} else {
|
||||||
// In the absense of compiler-generated preemption points
|
// In the absense of compiler-generated preemption points
|
||||||
// this is a good place to yield
|
// this is a good place to yield
|
||||||
task::yield();
|
task::yield();
|
||||||
|
}
|
||||||
|
move res
|
||||||
}
|
}
|
||||||
move res
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -27,8 +27,10 @@ extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn count(n: uint) -> uint {
|
fn count(n: uint) -> uint {
|
||||||
task::yield();
|
unsafe {
|
||||||
rustrt::rust_dbg_call(cb, n)
|
task::yield();
|
||||||
|
rustrt::rust_dbg_call(cb, n)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|||||||
@@ -26,8 +26,10 @@ fn getbig_call_c_and_fail(i: int) {
|
|||||||
if i != 0 {
|
if i != 0 {
|
||||||
getbig_call_c_and_fail(i - 1);
|
getbig_call_c_and_fail(i - 1);
|
||||||
} else {
|
} else {
|
||||||
rustrt::last_os_error();
|
unsafe {
|
||||||
fail;
|
rustrt::last_os_error();
|
||||||
|
fail;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,9 +11,11 @@
|
|||||||
#[abi = "cdecl"]
|
#[abi = "cdecl"]
|
||||||
#[link_name = "rustrt"]
|
#[link_name = "rustrt"]
|
||||||
extern {
|
extern {
|
||||||
fn last_os_error() -> ~str;
|
fn last_os_error() -> ~str;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
last_os_error();
|
unsafe {
|
||||||
|
let _ = last_os_error();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,5 +15,7 @@ extern mod rustrt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let _foo = rustrt::get_task_id;
|
unsafe {
|
||||||
|
let _foo = rustrt::get_task_id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,15 +19,17 @@ extern mod libc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn atol(s: ~str) -> int {
|
fn atol(s: ~str) -> int {
|
||||||
return str::as_buf(s, { |x, _len| libc::atol(x) });
|
return str::as_buf(s, { |x, _len| unsafe { libc::atol(x) } });
|
||||||
}
|
}
|
||||||
|
|
||||||
fn atoll(s: ~str) -> i64 {
|
fn atoll(s: ~str) -> i64 {
|
||||||
return str::as_buf(s, { |x, _len| libc::atoll(x) });
|
return str::as_buf(s, { |x, _len| unsafe { libc::atoll(x) } });
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
assert atol(~"1024") * 10 == atol(~"10240");
|
unsafe {
|
||||||
assert (atoll(~"11111111111111111") * 10i64)
|
assert atol(~"1024") * 10 == atol(~"10240");
|
||||||
== atoll(~"111111111111111110");
|
assert (atoll(~"11111111111111111") * 10i64)
|
||||||
|
== atoll(~"111111111111111110");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,8 +23,10 @@ extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn count(n: uint) -> uint {
|
fn count(n: uint) -> uint {
|
||||||
debug!("n = %?", n);
|
unsafe {
|
||||||
rustrt::rust_dbg_call(cb, n)
|
debug!("n = %?", n);
|
||||||
|
rustrt::rust_dbg_call(cb, n)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|||||||
@@ -23,8 +23,10 @@ extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn count(n: uint) -> uint {
|
fn count(n: uint) -> uint {
|
||||||
debug!("n = %?", n);
|
unsafe {
|
||||||
rustrt::rust_dbg_call(cb, n)
|
debug!("n = %?", n);
|
||||||
|
rustrt::rust_dbg_call(cb, n)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|||||||
@@ -27,8 +27,10 @@ extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn count(n: uint) -> uint {
|
fn count(n: uint) -> uint {
|
||||||
debug!("n = %?", n);
|
unsafe {
|
||||||
rustrt::rust_dbg_call(cb, n)
|
debug!("n = %?", n);
|
||||||
|
rustrt::rust_dbg_call(cb, n)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|||||||
@@ -23,8 +23,10 @@ extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn fact(n: uint) -> uint {
|
fn fact(n: uint) -> uint {
|
||||||
debug!("n = %?", n);
|
unsafe {
|
||||||
rustrt::rust_dbg_call(cb, n)
|
debug!("n = %?", n);
|
||||||
|
rustrt::rust_dbg_call(cb, n)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|||||||
@@ -14,8 +14,10 @@
|
|||||||
extern mod externcallback(vers = "0.1");
|
extern mod externcallback(vers = "0.1");
|
||||||
|
|
||||||
fn fact(n: uint) -> uint {
|
fn fact(n: uint) -> uint {
|
||||||
debug!("n = %?", n);
|
unsafe {
|
||||||
externcallback::rustrt::rust_dbg_call(externcallback::cb, n)
|
debug!("n = %?", n);
|
||||||
|
externcallback::rustrt::rust_dbg_call(externcallback::cb, n)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|||||||
@@ -27,7 +27,9 @@ extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn count(n: uint) -> uint {
|
fn count(n: uint) -> uint {
|
||||||
rustrt::rust_dbg_call(cb, n)
|
unsafe {
|
||||||
|
rustrt::rust_dbg_call(cb, n)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|||||||
@@ -23,8 +23,10 @@ extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn count(n: uint) -> uint {
|
fn count(n: uint) -> uint {
|
||||||
task::yield();
|
unsafe {
|
||||||
rustrt::rust_dbg_call(cb, n)
|
task::yield();
|
||||||
|
rustrt::rust_dbg_call(cb, n)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ extern mod rustrt2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
rustrt1::last_os_error();
|
unsafe {
|
||||||
rustrt2::last_os_error();
|
rustrt1::last_os_error();
|
||||||
|
rustrt2::last_os_error();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,5 +16,7 @@ extern mod rustrt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
rustrt::get_task_id();
|
unsafe {
|
||||||
|
rustrt::get_task_id();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,14 +23,18 @@ extern mod rusti {
|
|||||||
mod m {
|
mod m {
|
||||||
#[cfg(target_arch = "x86")]
|
#[cfg(target_arch = "x86")]
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
assert ::rusti::pref_align_of::<u64>() == 8u;
|
unsafe {
|
||||||
assert ::rusti::min_align_of::<u64>() == 4u;
|
assert ::rusti::pref_align_of::<u64>() == 8u;
|
||||||
|
assert ::rusti::min_align_of::<u64>() == 4u;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
assert ::rusti::pref_align_of::<u64>() == 8u;
|
unsafe {
|
||||||
assert ::rusti::min_align_of::<u64>() == 8u;
|
assert ::rusti::pref_align_of::<u64>() == 8u;
|
||||||
|
assert ::rusti::min_align_of::<u64>() == 8u;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,7 +42,9 @@ mod m {
|
|||||||
mod m {
|
mod m {
|
||||||
#[cfg(target_arch = "x86")]
|
#[cfg(target_arch = "x86")]
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
assert ::rusti::pref_align_of::<u64>() == 8u;
|
unsafe {
|
||||||
assert ::rusti::min_align_of::<u64>() == 8u;
|
assert ::rusti::pref_align_of::<u64>() == 8u;
|
||||||
|
assert ::rusti::min_align_of::<u64>() == 8u;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ extern mod cci_intrinsic;
|
|||||||
use cci_intrinsic::atomic_xchg;
|
use cci_intrinsic::atomic_xchg;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut x = 1;
|
unsafe {
|
||||||
atomic_xchg(&mut x, 5);
|
let mut x = 1;
|
||||||
assert x == 5;
|
atomic_xchg(&mut x, 5);
|
||||||
|
assert x == 5;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,33 +29,35 @@ extern mod rusti {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let x = ~mut 1;
|
unsafe {
|
||||||
|
let x = ~mut 1;
|
||||||
|
|
||||||
assert rusti::atomic_cxchg(x, 1, 2) == 1;
|
assert rusti::atomic_cxchg(x, 1, 2) == 1;
|
||||||
assert *x == 2;
|
assert *x == 2;
|
||||||
|
|
||||||
assert rusti::atomic_cxchg_acq(x, 1, 3) == 2;
|
assert rusti::atomic_cxchg_acq(x, 1, 3) == 2;
|
||||||
assert *x == 2;
|
assert *x == 2;
|
||||||
|
|
||||||
assert rusti::atomic_cxchg_rel(x, 2, 1) == 2;
|
assert rusti::atomic_cxchg_rel(x, 2, 1) == 2;
|
||||||
assert *x == 1;
|
assert *x == 1;
|
||||||
|
|
||||||
assert rusti::atomic_xchg(x, 0) == 1;
|
assert rusti::atomic_xchg(x, 0) == 1;
|
||||||
assert *x == 0;
|
assert *x == 0;
|
||||||
|
|
||||||
assert rusti::atomic_xchg_acq(x, 1) == 0;
|
assert rusti::atomic_xchg_acq(x, 1) == 0;
|
||||||
assert *x == 1;
|
assert *x == 1;
|
||||||
|
|
||||||
assert rusti::atomic_xchg_rel(x, 0) == 1;
|
assert rusti::atomic_xchg_rel(x, 0) == 1;
|
||||||
assert *x == 0;
|
assert *x == 0;
|
||||||
|
|
||||||
assert rusti::atomic_xadd(x, 1) == 0;
|
assert rusti::atomic_xadd(x, 1) == 0;
|
||||||
assert rusti::atomic_xadd_acq(x, 1) == 1;
|
assert rusti::atomic_xadd_acq(x, 1) == 1;
|
||||||
assert rusti::atomic_xadd_rel(x, 1) == 2;
|
assert rusti::atomic_xadd_rel(x, 1) == 2;
|
||||||
assert *x == 3;
|
assert *x == 3;
|
||||||
|
|
||||||
assert rusti::atomic_xsub(x, 1) == 3;
|
assert rusti::atomic_xsub(x, 1) == 3;
|
||||||
assert rusti::atomic_xsub_acq(x, 1) == 2;
|
assert rusti::atomic_xsub_acq(x, 1) == 2;
|
||||||
assert rusti::atomic_xsub_rel(x, 1) == 1;
|
assert rusti::atomic_xsub_rel(x, 1) == 1;
|
||||||
assert *x == 0;
|
assert *x == 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,9 @@ extern mod rusti {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
do rusti::frame_address |addr| {
|
unsafe {
|
||||||
assert addr.is_not_null();
|
do rusti::frame_address |addr| {
|
||||||
|
assert addr.is_not_null();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,14 +10,15 @@
|
|||||||
|
|
||||||
#[abi = "rust-intrinsic"]
|
#[abi = "rust-intrinsic"]
|
||||||
extern mod rusti {
|
extern mod rusti {
|
||||||
#[legacy_exports];
|
pub fn move_val_init<T>(dst: &mut T, -src: T);
|
||||||
fn move_val_init<T>(dst: &mut T, -src: T);
|
pub fn move_val<T>(dst: &mut T, -src: T);
|
||||||
fn move_val<T>(dst: &mut T, -src: T);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut x = @1;
|
unsafe {
|
||||||
let mut y = @2;
|
let mut x = @1;
|
||||||
rusti::move_val(&mut y, move x);
|
let mut y = @2;
|
||||||
assert *y == 1;
|
rusti::move_val(&mut y, move x);
|
||||||
|
assert *y == 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -35,86 +35,86 @@ extern mod rusti {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
unsafe {
|
||||||
|
use rusti::*;
|
||||||
|
|
||||||
use rusti::*;
|
assert(ctpop8(0i8) == 0i8);
|
||||||
|
assert(ctpop16(0i16) == 0i16);
|
||||||
|
assert(ctpop32(0i32) == 0i32);
|
||||||
|
assert(ctpop64(0i64) == 0i64);
|
||||||
|
|
||||||
assert(ctpop8(0i8) == 0i8);
|
assert(ctpop8(1i8) == 1i8);
|
||||||
assert(ctpop16(0i16) == 0i16);
|
assert(ctpop16(1i16) == 1i16);
|
||||||
assert(ctpop32(0i32) == 0i32);
|
assert(ctpop32(1i32) == 1i32);
|
||||||
assert(ctpop64(0i64) == 0i64);
|
assert(ctpop64(1i64) == 1i64);
|
||||||
|
|
||||||
assert(ctpop8(1i8) == 1i8);
|
assert(ctpop8(10i8) == 2i8);
|
||||||
assert(ctpop16(1i16) == 1i16);
|
assert(ctpop16(10i16) == 2i16);
|
||||||
assert(ctpop32(1i32) == 1i32);
|
assert(ctpop32(10i32) == 2i32);
|
||||||
assert(ctpop64(1i64) == 1i64);
|
assert(ctpop64(10i64) == 2i64);
|
||||||
|
|
||||||
assert(ctpop8(10i8) == 2i8);
|
assert(ctpop8(100i8) == 3i8);
|
||||||
assert(ctpop16(10i16) == 2i16);
|
assert(ctpop16(100i16) == 3i16);
|
||||||
assert(ctpop32(10i32) == 2i32);
|
assert(ctpop32(100i32) == 3i32);
|
||||||
assert(ctpop64(10i64) == 2i64);
|
assert(ctpop64(100i64) == 3i64);
|
||||||
|
|
||||||
assert(ctpop8(100i8) == 3i8);
|
assert(ctpop8(-1i8) == 8i8);
|
||||||
assert(ctpop16(100i16) == 3i16);
|
assert(ctpop16(-1i16) == 16i16);
|
||||||
assert(ctpop32(100i32) == 3i32);
|
assert(ctpop32(-1i32) == 32i32);
|
||||||
assert(ctpop64(100i64) == 3i64);
|
assert(ctpop64(-1i64) == 64i64);
|
||||||
|
|
||||||
assert(ctpop8(-1i8) == 8i8);
|
assert(ctlz8(0i8) == 8i8);
|
||||||
assert(ctpop16(-1i16) == 16i16);
|
assert(ctlz16(0i16) == 16i16);
|
||||||
assert(ctpop32(-1i32) == 32i32);
|
assert(ctlz32(0i32) == 32i32);
|
||||||
assert(ctpop64(-1i64) == 64i64);
|
assert(ctlz64(0i64) == 64i64);
|
||||||
|
|
||||||
assert(ctlz8(0i8) == 8i8);
|
assert(ctlz8(1i8) == 7i8);
|
||||||
assert(ctlz16(0i16) == 16i16);
|
assert(ctlz16(1i16) == 15i16);
|
||||||
assert(ctlz32(0i32) == 32i32);
|
assert(ctlz32(1i32) == 31i32);
|
||||||
assert(ctlz64(0i64) == 64i64);
|
assert(ctlz64(1i64) == 63i64);
|
||||||
|
|
||||||
assert(ctlz8(1i8) == 7i8);
|
assert(ctlz8(10i8) == 4i8);
|
||||||
assert(ctlz16(1i16) == 15i16);
|
assert(ctlz16(10i16) == 12i16);
|
||||||
assert(ctlz32(1i32) == 31i32);
|
assert(ctlz32(10i32) == 28i32);
|
||||||
assert(ctlz64(1i64) == 63i64);
|
assert(ctlz64(10i64) == 60i64);
|
||||||
|
|
||||||
assert(ctlz8(10i8) == 4i8);
|
assert(ctlz8(100i8) == 1i8);
|
||||||
assert(ctlz16(10i16) == 12i16);
|
assert(ctlz16(100i16) == 9i16);
|
||||||
assert(ctlz32(10i32) == 28i32);
|
assert(ctlz32(100i32) == 25i32);
|
||||||
assert(ctlz64(10i64) == 60i64);
|
assert(ctlz64(100i64) == 57i64);
|
||||||
|
|
||||||
assert(ctlz8(100i8) == 1i8);
|
assert(cttz8(-1i8) == 0i8);
|
||||||
assert(ctlz16(100i16) == 9i16);
|
assert(cttz16(-1i16) == 0i16);
|
||||||
assert(ctlz32(100i32) == 25i32);
|
assert(cttz32(-1i32) == 0i32);
|
||||||
assert(ctlz64(100i64) == 57i64);
|
assert(cttz64(-1i64) == 0i64);
|
||||||
|
|
||||||
assert(cttz8(-1i8) == 0i8);
|
assert(cttz8(0i8) == 8i8);
|
||||||
assert(cttz16(-1i16) == 0i16);
|
assert(cttz16(0i16) == 16i16);
|
||||||
assert(cttz32(-1i32) == 0i32);
|
assert(cttz32(0i32) == 32i32);
|
||||||
assert(cttz64(-1i64) == 0i64);
|
assert(cttz64(0i64) == 64i64);
|
||||||
|
|
||||||
assert(cttz8(0i8) == 8i8);
|
assert(cttz8(1i8) == 0i8);
|
||||||
assert(cttz16(0i16) == 16i16);
|
assert(cttz16(1i16) == 0i16);
|
||||||
assert(cttz32(0i32) == 32i32);
|
assert(cttz32(1i32) == 0i32);
|
||||||
assert(cttz64(0i64) == 64i64);
|
assert(cttz64(1i64) == 0i64);
|
||||||
|
|
||||||
assert(cttz8(1i8) == 0i8);
|
assert(cttz8(10i8) == 1i8);
|
||||||
assert(cttz16(1i16) == 0i16);
|
assert(cttz16(10i16) == 1i16);
|
||||||
assert(cttz32(1i32) == 0i32);
|
assert(cttz32(10i32) == 1i32);
|
||||||
assert(cttz64(1i64) == 0i64);
|
assert(cttz64(10i64) == 1i64);
|
||||||
|
|
||||||
assert(cttz8(10i8) == 1i8);
|
assert(cttz8(100i8) == 2i8);
|
||||||
assert(cttz16(10i16) == 1i16);
|
assert(cttz16(100i16) == 2i16);
|
||||||
assert(cttz32(10i32) == 1i32);
|
assert(cttz32(100i32) == 2i32);
|
||||||
assert(cttz64(10i64) == 1i64);
|
assert(cttz64(100i64) == 2i64);
|
||||||
|
|
||||||
assert(cttz8(100i8) == 2i8);
|
assert(cttz8(-1i8) == 0i8);
|
||||||
assert(cttz16(100i16) == 2i16);
|
assert(cttz16(-1i16) == 0i16);
|
||||||
assert(cttz32(100i32) == 2i32);
|
assert(cttz32(-1i32) == 0i32);
|
||||||
assert(cttz64(100i64) == 2i64);
|
assert(cttz64(-1i64) == 0i64);
|
||||||
|
|
||||||
assert(cttz8(-1i8) == 0i8);
|
|
||||||
assert(cttz16(-1i16) == 0i16);
|
|
||||||
assert(cttz32(-1i32) == 0i32);
|
|
||||||
assert(cttz64(-1i64) == 0i64);
|
|
||||||
|
|
||||||
assert(bswap16(0x0A0Bi16) == 0x0B0Ai16);
|
|
||||||
assert(bswap32(0x0ABBCC0Di32) == 0x0DCCBB0Ai32);
|
|
||||||
assert(bswap64(0x0122334455667708i64) == 0x0877665544332201i64);
|
|
||||||
|
|
||||||
|
assert(bswap16(0x0A0Bi16) == 0x0B0Ai16);
|
||||||
|
assert(bswap32(0x0ABBCC0Di32) == 0x0DCCBB0Ai32);
|
||||||
|
assert(bswap64(0x0122334455667708i64) == 0x0877665544332201i64);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,56 +49,57 @@ extern mod rusti {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
unsafe {
|
||||||
|
use rusti::*;
|
||||||
|
|
||||||
use rusti::*;
|
assert(sqrtf32(64f32).fuzzy_eq(&8f32));
|
||||||
|
assert(sqrtf64(64f64).fuzzy_eq(&8f64));
|
||||||
|
|
||||||
assert(sqrtf32(64f32).fuzzy_eq(&8f32));
|
assert(powif32(25f32, -2i32).fuzzy_eq(&0.0016f32));
|
||||||
assert(sqrtf64(64f64).fuzzy_eq(&8f64));
|
assert(powif64(23.2f64, 2i32).fuzzy_eq(&538.24f64));
|
||||||
|
|
||||||
assert(powif32(25f32, -2i32).fuzzy_eq(&0.0016f32));
|
assert(sinf32(0f32).fuzzy_eq(&0f32));
|
||||||
assert(powif64(23.2f64, 2i32).fuzzy_eq(&538.24f64));
|
assert(sinf64(f64::consts::pi / 2f64).fuzzy_eq(&1f64));
|
||||||
|
|
||||||
assert(sinf32(0f32).fuzzy_eq(&0f32));
|
assert(cosf32(0f32).fuzzy_eq(&1f32));
|
||||||
assert(sinf64(f64::consts::pi / 2f64).fuzzy_eq(&1f64));
|
assert(cosf64(f64::consts::pi * 2f64).fuzzy_eq(&1f64));
|
||||||
|
|
||||||
assert(cosf32(0f32).fuzzy_eq(&1f32));
|
assert(powf32(25f32, -2f32).fuzzy_eq(&0.0016f32));
|
||||||
assert(cosf64(f64::consts::pi * 2f64).fuzzy_eq(&1f64));
|
assert(powf64(400f64, 0.5f64).fuzzy_eq(&20f64));
|
||||||
|
|
||||||
assert(powf32(25f32, -2f32).fuzzy_eq(&0.0016f32));
|
assert(fabsf32(expf32(1f32) - f32::consts::e).fuzzy_eq(&0f32));
|
||||||
assert(powf64(400f64, 0.5f64).fuzzy_eq(&20f64));
|
assert(expf64(1f64).fuzzy_eq(&f64::consts::e));
|
||||||
|
|
||||||
assert(fabsf32(expf32(1f32) - f32::consts::e).fuzzy_eq(&0f32));
|
assert(exp2f32(10f32).fuzzy_eq(&1024f32));
|
||||||
assert(expf64(1f64).fuzzy_eq(&f64::consts::e));
|
assert(exp2f64(50f64).fuzzy_eq(&1125899906842624f64));
|
||||||
|
|
||||||
assert(exp2f32(10f32).fuzzy_eq(&1024f32));
|
assert(fabsf32(logf32(f32::consts::e) - 1f32).fuzzy_eq(&0f32));
|
||||||
assert(exp2f64(50f64).fuzzy_eq(&1125899906842624f64));
|
assert(logf64(1f64).fuzzy_eq(&0f64));
|
||||||
|
|
||||||
assert(fabsf32(logf32(f32::consts::e) - 1f32).fuzzy_eq(&0f32));
|
assert(log10f32(10f32).fuzzy_eq(&1f32));
|
||||||
assert(logf64(1f64).fuzzy_eq(&0f64));
|
assert(log10f64(f64::consts::e).fuzzy_eq(&f64::consts::log10_e));
|
||||||
|
|
||||||
assert(log10f32(10f32).fuzzy_eq(&1f32));
|
assert(log2f32(8f32).fuzzy_eq(&3f32));
|
||||||
assert(log10f64(f64::consts::e).fuzzy_eq(&f64::consts::log10_e));
|
assert(log2f64(f64::consts::e).fuzzy_eq(&f64::consts::log2_e));
|
||||||
|
|
||||||
assert(log2f32(8f32).fuzzy_eq(&3f32));
|
assert(fmaf32(1.0f32, 2.0f32, 5.0f32).fuzzy_eq(&7.0f32));
|
||||||
assert(log2f64(f64::consts::e).fuzzy_eq(&f64::consts::log2_e));
|
assert(fmaf64(0.0f64, -2.0f64, f64::consts::e).fuzzy_eq(&f64::consts::e));
|
||||||
|
|
||||||
assert(fmaf32(1.0f32, 2.0f32, 5.0f32).fuzzy_eq(&7.0f32));
|
assert(fabsf32(-1.0f32).fuzzy_eq(&1.0f32));
|
||||||
assert(fmaf64(0.0f64, -2.0f64, f64::consts::e).fuzzy_eq(&f64::consts::e));
|
assert(fabsf64(34.2f64).fuzzy_eq(&34.2f64));
|
||||||
|
|
||||||
assert(fabsf32(-1.0f32).fuzzy_eq(&1.0f32));
|
assert(floorf32(3.8f32).fuzzy_eq(&3.0f32));
|
||||||
assert(fabsf64(34.2f64).fuzzy_eq(&34.2f64));
|
assert(floorf64(-1.1f64).fuzzy_eq(&-2.0f64));
|
||||||
|
|
||||||
assert(floorf32(3.8f32).fuzzy_eq(&3.0f32));
|
// Causes linker error
|
||||||
assert(floorf64(-1.1f64).fuzzy_eq(&-2.0f64));
|
// undefined reference to llvm.ceil.f32/64
|
||||||
|
//assert(ceilf32(-2.3f32) == -2.0f32);
|
||||||
|
//assert(ceilf64(3.8f64) == 4.0f64);
|
||||||
|
|
||||||
// Causes linker error
|
// Causes linker error
|
||||||
// undefined reference to llvm.ceil.f32/64
|
// undefined reference to llvm.trunc.f32/64
|
||||||
//assert(ceilf32(-2.3f32) == -2.0f32);
|
//assert(truncf32(0.1f32) == 0.0f32);
|
||||||
//assert(ceilf64(3.8f64) == 4.0f64);
|
//assert(truncf64(-0.1f64) == 0.0f64);
|
||||||
|
}
|
||||||
// Causes linker error
|
|
||||||
// undefined reference to llvm.trunc.f32/64
|
|
||||||
//assert(truncf32(0.1f32) == 0.0f32);
|
|
||||||
//assert(truncf64(-0.1f64) == 0.0f64);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,9 @@ fn to_c_int(v: &mut int) -> &mut c_int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn lgamma(n: c_double, value: &mut int) -> c_double {
|
fn lgamma(n: c_double, value: &mut int) -> c_double {
|
||||||
return m::lgamma(n, to_c_int(value));
|
unsafe {
|
||||||
|
return m::lgamma(n, to_c_int(value));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[link_name = "m"]
|
#[link_name = "m"]
|
||||||
|
|||||||
@@ -1,27 +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.
|
|
||||||
|
|
||||||
/*
|
|
||||||
A reduced test case for Issue #506, provided by Rob Arnold.
|
|
||||||
|
|
||||||
Testing spawning foreign functions
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern mod std;
|
|
||||||
|
|
||||||
#[abi = "cdecl"]
|
|
||||||
extern mod rustrt {
|
|
||||||
#[legacy_exports];
|
|
||||||
fn rust_dbg_do_nothing();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
task::spawn(rustrt::rust_dbg_do_nothing);
|
|
||||||
}
|
|
||||||
@@ -16,7 +16,9 @@ extern mod rusti {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let addr = rusti::morestack_addr();
|
unsafe {
|
||||||
assert addr.is_not_null();
|
let addr = rusti::morestack_addr();
|
||||||
error!("%?", addr);
|
assert addr.is_not_null();
|
||||||
|
error!("%?", addr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -23,31 +23,33 @@ extern mod rustrt {
|
|||||||
fn rust_get_task();
|
fn rust_get_task();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn calllink01() { rustrt::rust_get_sched_id(); }
|
fn calllink01() { unsafe { rustrt::rust_get_sched_id(); } }
|
||||||
fn calllink02() { rustrt::last_os_error(); }
|
fn calllink02() { unsafe { rustrt::last_os_error(); } }
|
||||||
fn calllink03() { rustrt::rust_getcwd(); }
|
fn calllink03() { unsafe { rustrt::rust_getcwd(); } }
|
||||||
fn calllink08() { rustrt::get_task_id(); }
|
fn calllink08() { unsafe { rustrt::get_task_id(); } }
|
||||||
fn calllink09() { rustrt::rust_sched_threads(); }
|
fn calllink09() { unsafe { rustrt::rust_sched_threads(); } }
|
||||||
fn calllink10() { rustrt::rust_get_task(); }
|
fn calllink10() { unsafe { rustrt::rust_get_task(); } }
|
||||||
|
|
||||||
fn runtest(f: fn~(), frame_backoff: u32) {
|
fn runtest(f: fn~(), frame_backoff: u32) {
|
||||||
runtest2(f, frame_backoff, 0 as *u8);
|
runtest2(f, frame_backoff, 0 as *u8);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn runtest2(f: fn~(), frame_backoff: u32, last_stk: *u8) -> u32 {
|
fn runtest2(f: fn~(), frame_backoff: u32, last_stk: *u8) -> u32 {
|
||||||
let curr_stk = rustrt::debug_get_stk_seg();
|
unsafe {
|
||||||
if (last_stk != curr_stk && last_stk != 0 as *u8) {
|
let curr_stk = rustrt::debug_get_stk_seg();
|
||||||
// We switched stacks, go back and try to hit the dynamic linker
|
if (last_stk != curr_stk && last_stk != 0 as *u8) {
|
||||||
frame_backoff
|
// We switched stacks, go back and try to hit the dynamic linker
|
||||||
} else {
|
frame_backoff
|
||||||
let frame_backoff = runtest2(copy f, frame_backoff, curr_stk);
|
|
||||||
if frame_backoff > 1u32 {
|
|
||||||
frame_backoff - 1u32
|
|
||||||
} else if frame_backoff == 1u32 {
|
|
||||||
f();
|
|
||||||
0u32
|
|
||||||
} else {
|
} else {
|
||||||
0u32
|
let frame_backoff = runtest2(copy f, frame_backoff, curr_stk);
|
||||||
|
if frame_backoff > 1u32 {
|
||||||
|
frame_backoff - 1u32
|
||||||
|
} else if frame_backoff == 1u32 {
|
||||||
|
f();
|
||||||
|
0u32
|
||||||
|
} else {
|
||||||
|
0u32
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,22 +45,23 @@ mod m {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
unsafe {
|
||||||
|
let x = {c8: 22u8, t: {c64: 44u32}};
|
||||||
|
|
||||||
let x = {c8: 22u8, t: {c64: 44u32}};
|
// Send it through the shape code
|
||||||
|
let y = fmt!("%?", x);
|
||||||
|
|
||||||
// Send it through the shape code
|
debug!("align inner = %?", rusti::min_align_of::<inner>());
|
||||||
let y = fmt!("%?", x);
|
debug!("size outer = %?", sys::size_of::<outer>());
|
||||||
|
debug!("y = %s", y);
|
||||||
|
|
||||||
debug!("align inner = %?", rusti::min_align_of::<inner>());
|
// per clang/gcc the alignment of `inner` is 4 on x86.
|
||||||
debug!("size outer = %?", sys::size_of::<outer>());
|
assert rusti::min_align_of::<inner>() == m::align();
|
||||||
debug!("y = %s", y);
|
|
||||||
|
|
||||||
// per clang/gcc the alignment of `inner` is 4 on x86.
|
// per clang/gcc the size of `outer` should be 12
|
||||||
assert rusti::min_align_of::<inner>() == m::align();
|
// because `inner`s alignment was 4.
|
||||||
|
assert sys::size_of::<outer>() == m::size();
|
||||||
|
|
||||||
// per clang/gcc the size of `outer` should be 12
|
assert y == ~"{c8: 22, t: {c64: 44}}";
|
||||||
// because `inner`s alignment was 4.
|
}
|
||||||
assert sys::size_of::<outer>() == m::size();
|
|
||||||
|
|
||||||
assert y == ~"{c8: 22, t: {c64: 44}}";
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,22 +62,23 @@ mod m {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
unsafe {
|
||||||
|
let x = {c8: 22u8, t: {c64: 44u64}};
|
||||||
|
|
||||||
let x = {c8: 22u8, t: {c64: 44u64}};
|
// Send it through the shape code
|
||||||
|
let y = fmt!("%?", x);
|
||||||
|
|
||||||
// Send it through the shape code
|
debug!("align inner = %?", rusti::min_align_of::<inner>());
|
||||||
let y = fmt!("%?", x);
|
debug!("size outer = %?", sys::size_of::<outer>());
|
||||||
|
debug!("y = %s", y);
|
||||||
|
|
||||||
debug!("align inner = %?", rusti::min_align_of::<inner>());
|
// per clang/gcc the alignment of `inner` is 4 on x86.
|
||||||
debug!("size outer = %?", sys::size_of::<outer>());
|
assert rusti::min_align_of::<inner>() == m::m::align();
|
||||||
debug!("y = %s", y);
|
|
||||||
|
|
||||||
// per clang/gcc the alignment of `inner` is 4 on x86.
|
// per clang/gcc the size of `outer` should be 12
|
||||||
assert rusti::min_align_of::<inner>() == m::m::align();
|
// because `inner`s alignment was 4.
|
||||||
|
assert sys::size_of::<outer>() == m::m::size();
|
||||||
|
|
||||||
// per clang/gcc the size of `outer` should be 12
|
assert y == ~"{c8: 22, t: {c64: 44}}";
|
||||||
// because `inner`s alignment was 4.
|
}
|
||||||
assert sys::size_of::<outer>() == m::m::size();
|
|
||||||
|
|
||||||
assert y == ~"{c8: 22, t: {c64: 44}}";
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -483,10 +483,12 @@ impl my_visitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn visit_inner(inner: *TyDesc) -> bool {
|
fn visit_inner(inner: *TyDesc) -> bool {
|
||||||
let u = my_visitor(*self);
|
unsafe {
|
||||||
let v = ptr_visit_adaptor({inner: u});
|
let u = my_visitor(*self);
|
||||||
visit_tydesc(inner, v as TyVisitor);
|
let v = ptr_visit_adaptor({inner: u});
|
||||||
true
|
visit_tydesc(inner, v as TyVisitor);
|
||||||
|
true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -621,21 +623,25 @@ fn get_tydesc_for<T>(&&_t: T) -> *TyDesc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let r = (1,2,3,true,false,{x:5,y:4,z:3});
|
unsafe {
|
||||||
let p = ptr::addr_of(&r) as *c_void;
|
let r = (1,2,3,true,false,{x:5,y:4,z:3});
|
||||||
let u = my_visitor(@{mut ptr1: p,
|
let p = ptr::addr_of(&r) as *c_void;
|
||||||
mut ptr2: p,
|
let u = my_visitor(@{mut ptr1: p,
|
||||||
mut vals: ~[]});
|
mut ptr2: p,
|
||||||
let v = ptr_visit_adaptor({inner: u});
|
mut vals: ~[]});
|
||||||
let td = get_tydesc_for(r);
|
let v = ptr_visit_adaptor({inner: u});
|
||||||
unsafe { error!("tydesc sz: %u, align: %u",
|
let td = get_tydesc_for(r);
|
||||||
(*td).size, (*td).align); }
|
unsafe { error!("tydesc sz: %u, align: %u",
|
||||||
let v = v as TyVisitor;
|
(*td).size, (*td).align); }
|
||||||
visit_tydesc(td, v);
|
let v = v as TyVisitor;
|
||||||
|
visit_tydesc(td, v);
|
||||||
|
|
||||||
for (copy u.vals).each |s| {
|
for (copy u.vals).each |s| {
|
||||||
io::println(fmt!("val: %s", *s));
|
io::println(fmt!("val: %s", *s));
|
||||||
|
}
|
||||||
|
error!("%?", copy u.vals);
|
||||||
|
assert u.vals == ~[
|
||||||
|
~"1", ~"2", ~"3", ~"true", ~"false", ~"5", ~"4", ~"3"
|
||||||
|
];
|
||||||
}
|
}
|
||||||
error!("%?", copy u.vals);
|
|
||||||
assert u.vals == ~[~"1", ~"2", ~"3", ~"true", ~"false", ~"5", ~"4", ~"3"];
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,11 +36,13 @@ fn main() {
|
|||||||
let new_task_id = rustrt::rust_new_task_in_sched(new_sched_id);
|
let new_task_id = rustrt::rust_new_task_in_sched(new_sched_id);
|
||||||
assert !new_task_id.is_null();
|
assert !new_task_id.is_null();
|
||||||
let f = fn~() {
|
let f = fn~() {
|
||||||
let child_sched_id = rustrt::rust_get_sched_id();
|
unsafe {
|
||||||
error!("child_sched_id %?", child_sched_id);
|
let child_sched_id = rustrt::rust_get_sched_id();
|
||||||
assert child_sched_id != parent_sched_id;
|
error!("child_sched_id %?", child_sched_id);
|
||||||
assert child_sched_id == new_sched_id;
|
assert child_sched_id != parent_sched_id;
|
||||||
oldcomm::send(ch, ());
|
assert child_sched_id == new_sched_id;
|
||||||
|
oldcomm::send(ch, ());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
let fptr = cast::reinterpret_cast(&ptr::addr_of(&f));
|
let fptr = cast::reinterpret_cast(&ptr::addr_of(&f));
|
||||||
rustrt::start_task(new_task_id, fptr);
|
rustrt::start_task(new_task_id, fptr);
|
||||||
|
|||||||
@@ -19,33 +19,37 @@ extern mod rustrt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn test1() {
|
fn test1() {
|
||||||
let q = { a: 0xaaaa_aaaa_aaaa_aaaa_u64,
|
unsafe {
|
||||||
b: 0xbbbb_bbbb_bbbb_bbbb_u64,
|
let q = { a: 0xaaaa_aaaa_aaaa_aaaa_u64,
|
||||||
c: 0xcccc_cccc_cccc_cccc_u64,
|
b: 0xbbbb_bbbb_bbbb_bbbb_u64,
|
||||||
d: 0xdddd_dddd_dddd_dddd_u64 };
|
c: 0xcccc_cccc_cccc_cccc_u64,
|
||||||
let qq = rustrt::debug_abi_1(q);
|
d: 0xdddd_dddd_dddd_dddd_u64 };
|
||||||
error!("a: %x", qq.a as uint);
|
let qq = rustrt::debug_abi_1(q);
|
||||||
error!("b: %x", qq.b as uint);
|
error!("a: %x", qq.a as uint);
|
||||||
error!("c: %x", qq.c as uint);
|
error!("b: %x", qq.b as uint);
|
||||||
error!("d: %x", qq.d as uint);
|
error!("c: %x", qq.c as uint);
|
||||||
assert qq.a == q.c + 1u64;
|
error!("d: %x", qq.d as uint);
|
||||||
assert qq.b == q.d - 1u64;
|
assert qq.a == q.c + 1u64;
|
||||||
assert qq.c == q.a + 1u64;
|
assert qq.b == q.d - 1u64;
|
||||||
assert qq.d == q.b - 1u64;
|
assert qq.c == q.a + 1u64;
|
||||||
|
assert qq.d == q.b - 1u64;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
fn test2() {
|
fn test2() {
|
||||||
let f = { a: 1.234567890e-15_f64,
|
unsafe {
|
||||||
b: 0b_1010_1010_u8,
|
let f = { a: 1.234567890e-15_f64,
|
||||||
c: 1.0987654321e-15_f64 };
|
b: 0b_1010_1010_u8,
|
||||||
let ff = rustrt::debug_abi_2(f);
|
c: 1.0987654321e-15_f64 };
|
||||||
error!("a: %f", ff.a as float);
|
let ff = rustrt::debug_abi_2(f);
|
||||||
error!("b: %u", ff.b as uint);
|
error!("a: %f", ff.a as float);
|
||||||
error!("c: %f", ff.c as float);
|
error!("b: %u", ff.b as uint);
|
||||||
assert ff.a == f.c + 1.0f64;
|
error!("c: %f", ff.c as float);
|
||||||
assert ff.b == 0xff_u8;
|
assert ff.a == f.c + 1.0f64;
|
||||||
assert ff.c == f.a - 1.0f64;
|
assert ff.b == 0xff_u8;
|
||||||
|
assert ff.c == f.a - 1.0f64;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "x86")]
|
#[cfg(target_arch = "x86")]
|
||||||
|
|||||||
Reference in New Issue
Block a user