replace impl of globa_async_handle with one using atomic compare-and-swap

This commit is contained in:
Jeff Olson
2012-04-16 23:21:27 -07:00
committed by Brian Anderson
parent d7a87aa0a1
commit 253fad7788
5 changed files with 43 additions and 29 deletions

View File

@@ -15,8 +15,10 @@ import ll = uv_ll;
native mod rustrt { native mod rustrt {
fn rust_uv_get_kernel_global_chan_ptr() -> *libc::uintptr_t; fn rust_uv_get_kernel_global_chan_ptr() -> *libc::uintptr_t;
fn rust_uv_get_kernel_global_async_handle() -> **libc::c_void; fn rust_uv_get_kernel_global_async_handle() -> *libc::uintptr_t;
fn rust_uv_set_kernel_global_async_handle(handle: *ll::uv_async_t); fn rust_compare_and_swap_ptr(address: *libc::uintptr_t,
oldval: libc::uintptr_t,
newval: libc::uintptr_t) -> bool;
} }
#[doc = " #[doc = "
@@ -75,7 +77,8 @@ fn get_global_loop() -> high_level_loop unsafe {
outer_global_loop_body(port); outer_global_loop_body(port);
}; };
log(debug, "after priv::chan_from_global_ptr"); log(debug, "after priv::chan_from_global_ptr");
let handle = get_global_async_handle(); let handle = get_global_async_handle_native_representation()
as **ll::uv_async_t;
ret { async_handle: handle, op_chan: chan }; ret { async_handle: handle, op_chan: chan };
} }
} }
@@ -104,7 +107,7 @@ unsafe fn run_high_level_loop(loop_ptr: *libc::c_void,
msg_po: comm::port<high_level_msg>, msg_po: comm::port<high_level_msg>,
before_run: fn~(*global_loop_data), before_run: fn~(*global_loop_data),
before_msg_drain: fn~() -> bool, before_msg_drain: fn~() -> bool,
before_tear_down: fn~()) { before_tear_down: fn~(*global_loop_data)) {
// set up the special async handle we'll use to allow multi-task // set up the special async handle we'll use to allow multi-task
// communication with this loop // communication with this loop
let async = ll::async_t(); let async = ll::async_t();
@@ -117,7 +120,7 @@ unsafe fn run_high_level_loop(loop_ptr: *libc::c_void,
async_handle: async_handle, async_handle: async_handle,
mut active: true, mut active: true,
before_msg_drain: before_msg_drain, before_msg_drain: before_msg_drain,
before_tear_down: before_tear_down, before_tear_down: gdc_callback(before_tear_down),
msg_po_ptr: ptr::addr_of(msg_po), msg_po_ptr: ptr::addr_of(msg_po),
mut refd_handles: [mut], mut refd_handles: [mut],
mut unrefd_handles: [mut] mut unrefd_handles: [mut]
@@ -263,7 +266,11 @@ crust fn tear_down_close_cb(handle: *ll::uv_async_t) unsafe {
fn high_level_tear_down(data: *global_loop_data) unsafe { fn high_level_tear_down(data: *global_loop_data) unsafe {
log(debug, "high_level_tear_down() called, close async_handle"); log(debug, "high_level_tear_down() called, close async_handle");
// call user-suppled before_tear_down cb // call user-suppled before_tear_down cb
(*data).before_tear_down(); alt (*data).before_tear_down {
gdc_callback(cb) {
cb(data);
}
}
let async_handle = (*data).async_handle; let async_handle = (*data).async_handle;
ll::close(async_handle as *libc::c_void, tear_down_close_cb); ll::close(async_handle as *libc::c_void, tear_down_close_cb);
} }
@@ -330,19 +337,32 @@ enum high_level_msg {
tear_down tear_down
} }
fn get_global_async_handle() -> **ll::uv_async_t { unsafe fn get_global_async_handle_native_representation()
ret rustrt::rust_uv_get_kernel_global_async_handle() as **ll::uv_async_t; -> *libc::uintptr_t {
ret rustrt::rust_uv_get_kernel_global_async_handle();
} }
fn set_global_async_handle(handle: *ll::uv_async_t) { unsafe fn get_global_async_handle() -> *ll::uv_async_t {
rustrt::rust_uv_set_kernel_global_async_handle(handle); ret (*get_global_async_handle_native_representation()) as *ll::uv_async_t;
}
unsafe fn set_global_async_handle(old: *ll::uv_async_t,
new_ptr: *ll::uv_async_t) {
rustrt::rust_compare_and_swap_ptr(
get_global_async_handle_native_representation(),
old as libc::uintptr_t,
new_ptr as libc::uintptr_t);
}
enum global_data_callback {
gdc_callback(fn~(*global_loop_data))
} }
type global_loop_data = { type global_loop_data = {
async_handle: *ll::uv_async_t, async_handle: *ll::uv_async_t,
mut active: bool, mut active: bool,
before_msg_drain: fn~() -> bool, before_msg_drain: fn~() -> bool,
before_tear_down: fn~(), before_tear_down: global_data_callback,
msg_po_ptr: *comm::port<high_level_msg>, msg_po_ptr: *comm::port<high_level_msg>,
mut refd_handles: [mut *libc::c_void], mut refd_handles: [mut *libc::c_void],
mut unrefd_handles: [mut *libc::c_void] mut unrefd_handles: [mut *libc::c_void]
@@ -399,7 +419,8 @@ unsafe fn inner_global_loop_body(weak_exit_po_in: comm::port<()>,
// before_run // before_run
{|data| {|data|
// set the handle as the global // set the handle as the global
set_global_async_handle((*data).async_handle); set_global_async_handle(0u as *ll::uv_async_t,
(*data).async_handle);
// when this is ran, our async_handle is set up, so let's // when this is ran, our async_handle is set up, so let's
// do an async_send with it // do an async_send with it
ll::async_send((*data).async_handle); ll::async_send((*data).async_handle);
@@ -422,8 +443,9 @@ unsafe fn inner_global_loop_body(weak_exit_po_in: comm::port<()>,
} }
}, },
// before_tear_down // before_tear_down
{|| {|data|
set_global_async_handle(0 as *ll::uv_async_t); set_global_async_handle((*data).async_handle,
0 as *ll::uv_async_t);
}); });
// supposed to return a bool to indicate to the enclosing loop whether // supposed to return a bool to indicate to the enclosing loop whether
// it should continue or not.. // it should continue or not..

View File

@@ -27,10 +27,9 @@ rust_kernel::rust_kernel(rust_env *env) :
// set up storage of pointers needed to // set up storage of pointers needed to
// access the global loop. // access the global loop.
global_loop_chan = 0; global_loop_chan = 0;
int foo = 0; async_handle_inner = (uintptr_t)0;
async_handle_stub = (void*)&foo; global_async_handle = &async_handle_inner;
global_async_handle = &async_handle_stub; *global_async_handle = (uintptr_t)0;
*global_async_handle = (void*)0;
// Create the single threaded scheduler that will run on the platform's // Create the single threaded scheduler that will run on the platform's
// main thread // main thread

View File

@@ -75,8 +75,8 @@ class rust_kernel {
// Used to communicate with the process-side, global libuv loop // Used to communicate with the process-side, global libuv loop
uintptr_t global_loop_chan; uintptr_t global_loop_chan;
void* async_handle_stub; uintptr_t async_handle_inner;
void** global_async_handle; uintptr_t* global_async_handle;
public: public:
struct rust_env *env; struct rust_env *env;
@@ -124,9 +124,7 @@ public:
bool send_to_port(rust_port_id chan, void *sptr); bool send_to_port(rust_port_id chan, void *sptr);
uintptr_t* get_global_loop() { return &global_loop_chan; } uintptr_t* get_global_loop() { return &global_loop_chan; }
void** get_global_async_handle() { return global_async_handle; } uintptr_t* get_global_async_handle() { return global_async_handle; }
void set_global_async_handle(void* handle) {
*global_async_handle = handle; }
}; };
template <typename T> struct kernel_owned { template <typename T> struct kernel_owned {

View File

@@ -446,11 +446,7 @@ rust_uv_get_kernel_global_chan_ptr() {
return result; return result;
} }
extern "C" void** extern "C" uintptr_t*
rust_uv_get_kernel_global_async_handle() { rust_uv_get_kernel_global_async_handle() {
return rust_get_current_task()->kernel->get_global_async_handle(); return rust_get_current_task()->kernel->get_global_async_handle();
} }
extern "C" void
rust_uv_set_kernel_global_async_handle(uv_async_t* handle) {
rust_get_current_task()->kernel->set_global_async_handle((void*)handle);
}

View File

@@ -138,7 +138,6 @@ rust_uv_get_base_from_buf
rust_uv_get_len_from_buf rust_uv_get_len_from_buf
rust_uv_get_kernel_global_chan_ptr rust_uv_get_kernel_global_chan_ptr
rust_uv_get_kernel_global_async_handle rust_uv_get_kernel_global_async_handle
rust_uv_set_kernel_global_async_handle
rust_dbg_lock_create rust_dbg_lock_create
rust_dbg_lock_destroy rust_dbg_lock_destroy
rust_dbg_lock_lock rust_dbg_lock_lock