diff --git a/src/libcore/private.rs b/src/libcore/private.rs index aa976ee745d..c3068d6f61b 100644 --- a/src/libcore/private.rs +++ b/src/libcore/private.rs @@ -95,163 +95,11 @@ fn test_run_in_bare_thread() unsafe { #[allow(non_camel_case_types)] // runtime type type rust_port_id = uint; -type GlobalPtr = *libc::uintptr_t; - fn compare_and_swap(address: &mut int, oldval: int, newval: int) -> bool { let old = rusti::atomic_cxchg(address, oldval, newval); old == oldval } -/** - * Atomically gets a channel from a pointer to a pointer-sized memory location - * or, if no channel exists creates and installs a new channel and sets up a - * new task to receive from it. - */ -pub unsafe fn chan_from_global_ptr( - global: GlobalPtr, - task_fn: fn() -> task::TaskBuilder, - f: fn~(oldcomm::Port) -) -> oldcomm::Chan { - - enum Msg { - Proceed, - Abort - } - - log(debug,~"ENTERING chan_from_global_ptr, before is_prob_zero check"); - let is_probably_zero = *global == 0u; - log(debug,~"after is_prob_zero check"); - if is_probably_zero { - log(debug,~"is probably zero..."); - // There's no global channel. We must make it - - let (setup1_po, setup1_ch) = pipes::stream(); - let (setup2_po, setup2_ch) = pipes::stream(); - - // FIXME #4422: Ugly type inference hint - let setup2_po: pipes::Port = setup2_po; - - do task_fn().spawn |move f, move setup1_ch, move setup2_po| { - let po = oldcomm::Port::(); - let ch = oldcomm::Chan(&po); - setup1_ch.send(ch); - - // Wait to hear if we are the official instance of - // this global task - match setup2_po.recv() { - Proceed => f(move po), - Abort => () - } - }; - - log(debug,~"before setup recv.."); - // This is the proposed global channel - let ch = setup1_po.recv(); - // 0 is our sentinal value. It is not a valid channel - assert *ch != 0; - - // Install the channel - log(debug,~"BEFORE COMPARE AND SWAP"); - let swapped = compare_and_swap( - cast::reinterpret_cast(&global), - 0, cast::reinterpret_cast(&ch)); - log(debug,fmt!("AFTER .. swapped? %?", swapped)); - - if swapped { - // Success! - setup2_ch.send(Proceed); - ch - } else { - // Somebody else got in before we did - setup2_ch.send(Abort); - cast::reinterpret_cast(&*global) - } - } else { - log(debug, ~"global != 0"); - cast::reinterpret_cast(&*global) - } -} - -#[test] -pub fn test_from_global_chan1() { - - // This is unreadable, right? - - // The global channel - let globchan = 0; - let globchanp = ptr::addr_of(&globchan); - - // Create the global channel, attached to a new task - let ch = unsafe { - do chan_from_global_ptr(globchanp, task::task) |po| { - let ch = oldcomm::recv(po); - oldcomm::send(ch, true); - let ch = oldcomm::recv(po); - oldcomm::send(ch, true); - } - }; - // Talk to it - let po = oldcomm::Port(); - oldcomm::send(ch, oldcomm::Chan(&po)); - assert oldcomm::recv(po) == true; - - // This one just reuses the previous channel - let ch = unsafe { - do chan_from_global_ptr(globchanp, task::task) |po| { - let ch = oldcomm::recv(po); - oldcomm::send(ch, false); - } - }; - - // Talk to the original global task - let po = oldcomm::Port(); - oldcomm::send(ch, oldcomm::Chan(&po)); - assert oldcomm::recv(po) == true; -} - -#[test] -pub fn test_from_global_chan2() { - - for iter::repeat(100) { - // The global channel - let globchan = 0; - let globchanp = ptr::addr_of(&globchan); - - let resultpo = oldcomm::Port(); - let resultch = oldcomm::Chan(&resultpo); - - // Spawn a bunch of tasks that all want to compete to - // create the global channel - for uint::range(0, 10) |i| { - do task::spawn { - let ch = unsafe { - do chan_from_global_ptr( - globchanp, task::task) |po| { - - for uint::range(0, 10) |_j| { - let ch = oldcomm::recv(po); - oldcomm::send(ch, {i}); - } - } - }; - let po = oldcomm::Port(); - oldcomm::send(ch, oldcomm::Chan(&po)); - // We are The winner if our version of the - // task was installed - let winner = oldcomm::recv(po); - oldcomm::send(resultch, winner == i); - } - } - // There should be only one winner - let mut winners = 0u; - for uint::range(0u, 10u) |_i| { - let res = oldcomm::recv(resultpo); - if res { winners += 1u }; - } - assert winners == 1u; - } -} - /** * Convert the current task to a 'weak' task temporarily * diff --git a/src/libstd/uv_global_loop.rs b/src/libstd/uv_global_loop.rs index 097e923225a..c99bcaa54fa 100644 --- a/src/libstd/uv_global_loop.rs +++ b/src/libstd/uv_global_loop.rs @@ -75,10 +75,10 @@ fn get_monitor_task_gl() -> IoTask unsafe { debug!("global monitor task starting"); // As a weak task the runtime will notify us when to exit do weaken_task |weak_exit_po| { - debug!("global monitor task is now weak"); + debug!("global monitor task is weak"); weak_exit_po.recv(); iotask::exit(&iotask); - debug!("global monitor task is leaving weakend state"); + debug!("global monitor task is unweak"); }; debug!("global monitor task exiting"); }