replace impl of globa_async_handle with one using atomic compare-and-swap
This commit is contained in:
committed by
Brian Anderson
parent
d7a87aa0a1
commit
253fad7788
@@ -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..
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user