diff --git a/src/rt/rust_proxy.h b/src/rt/rust_proxy.h index e2fa5e00546..bf12e1d5f0e 100644 --- a/src/rt/rust_proxy.h +++ b/src/rt/rust_proxy.h @@ -1,30 +1,55 @@ +#ifndef RUST_PROXY_H +#define RUST_PROXY_H + /** * A proxy object is a wrapper around other Rust objects. One use of the proxy * object is to mitigate access between tasks in different thread domains. */ -#ifndef RUST_PROXY_H -#define RUST_PROXY_H - +template struct rust_proxy; +/** + * The base class of all objects that may delegate. + */ template struct -rust_proxy_delegate : public rc_base { +maybe_proxy : public rc_base, public rust_cond { protected: T *_delegate; public: - rust_proxy_delegate(T * delegate) : _delegate(delegate) { + maybe_proxy(T * delegate) : _delegate(delegate) { + + } + T *delegate() { + return _delegate; + } + bool is_proxy() { + return _delegate != this; + } + rust_proxy *as_proxy() { + return (rust_proxy *) this; + } + T *as_delegate() { + I(_delegate->get_dom(), !is_proxy()); + return (T *) this; } - T *delegate() { return _delegate; } }; +/** + * A proxy object that delegates to another. + */ template struct -rust_proxy : public rust_proxy_delegate, +rust_proxy : public maybe_proxy, public dom_owned > { +private: + bool _strong; public: rust_dom *dom; - rust_proxy(rust_dom *dom, T *delegate) : - rust_proxy_delegate (delegate), - dom(dom) { - delegate->ref(); + rust_proxy(rust_dom *dom, T *delegate, bool strong) : + maybe_proxy (delegate), _strong(strong), dom(dom) { + this->dom->log(rust_log::COMM, + "new proxy: 0x%" PRIxPTR " => 0x%" PRIxPTR, this, delegate); + if (strong) { + delegate->ref(); + } } }; diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp index 2bb0954196e..189824ac16a 100644 --- a/src/rt/rust_task.cpp +++ b/src/rt/rust_task.cpp @@ -53,7 +53,7 @@ align_down(uintptr_t sp) rust_task::rust_task(rust_dom *dom, rust_task *spawner) : - rust_proxy_delegate(this), + maybe_proxy(this), stk(new_stk(dom, 0)), runtime_sp(0), rust_sp(stk->limit), diff --git a/src/rt/rust_task.h b/src/rt/rust_task.h index a5cca2cbfc0..0c723a9dd5d 100644 --- a/src/rt/rust_task.h +++ b/src/rt/rust_task.h @@ -5,9 +5,8 @@ #ifndef RUST_TASK_H #define RUST_TASK_H struct -rust_task : public rust_proxy_delegate, - public dom_owned, - public rust_cond +rust_task : public maybe_proxy, + public dom_owned { // Fields known to the compiler. stk_seg *stk; diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp index 77d39b859b3..e4604049c4d 100644 --- a/src/rt/rust_upcall.cpp +++ b/src/rt/rust_upcall.cpp @@ -105,7 +105,7 @@ extern "C" CDECL void upcall_del_chan(rust_task *task, rust_chan *chan) { */ extern "C" CDECL rust_chan * upcall_clone_chan(rust_task *task, - rust_proxy_delegate *spawnee_proxy, + maybe_proxy *spawnee_proxy, rust_chan *chan) { LOG_UPCALL_ENTRY(task); rust_task *spawnee = spawnee_proxy->delegate(); @@ -121,8 +121,8 @@ extern "C" CDECL void upcall_yield(rust_task *task) { task->yield(1); } -extern "C" CDECL void upcall_join(rust_task *task, - rust_proxy_delegate *proxy) { +extern "C" CDECL void +upcall_join(rust_task *task, maybe_proxy *proxy) { LOG_UPCALL_ENTRY(task); task->log(rust_log::UPCALL | rust_log::COMM, "join proxy 0x%" PRIxPTR " -> task = 0x%" PRIxPTR, @@ -194,7 +194,7 @@ extern "C" CDECL void upcall_fail(rust_task *task, char const *expr, * Called whenever a task's ref count drops to zero. */ extern "C" CDECL void -upcall_kill(rust_task *task, rust_proxy_delegate *target_proxy) { +upcall_kill(rust_task *task, maybe_proxy *target_proxy) { LOG_UPCALL_ENTRY(task); rust_task *target_task = target_proxy->delegate(); if (target_proxy != target_task) { @@ -504,7 +504,7 @@ upcall_start_task(rust_task *spawner, rust_task *task, return task; } -extern "C" CDECL rust_proxy_delegate * +extern "C" CDECL maybe_proxy * upcall_new_thread(rust_task *task) { LOG_UPCALL_ENTRY(task); @@ -516,16 +516,17 @@ upcall_new_thread(rust_task *task) { "upcall new_thread() = dom 0x%" PRIxPTR " task 0x%" PRIxPTR, new_dom, new_dom->root_task); rust_proxy *proxy = - new (old_dom) rust_proxy(old_dom, new_dom->root_task); + new (old_dom) rust_proxy(old_dom, + new_dom->root_task, true); task->log(rust_log::UPCALL | rust_log::MEM, "new proxy = 0x%" PRIxPTR " -> task = 0x%" PRIxPTR, proxy, proxy->delegate()); return proxy; } -extern "C" CDECL rust_proxy_delegate * +extern "C" CDECL maybe_proxy * upcall_start_thread(rust_task *spawner, - rust_proxy_delegate *root_task_proxy, + maybe_proxy *root_task_proxy, uintptr_t exit_task_glue, uintptr_t spawnee_fn, size_t callsz) { LOG_UPCALL_ENTRY(spawner);