Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
d1dbb999
R
Rust
项目概览
int
/
Rust
大约 1 年 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
d1dbb999
编写于
7月 29, 2011
作者:
E
Eric Holk
提交者:
Graydon Hoare
7月 29, 2011
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Removing proxies and message queues.
上级
bc4e9afe
变更
17
隐藏空白更改
内联
并排
Showing
17 changed file
with
64 addition
and
690 deletion
+64
-690
mk/rt.mk
mk/rt.mk
+0
-3
src/rt/rust.cpp
src/rt/rust.cpp
+0
-1
src/rt/rust_chan.cpp
src/rt/rust_chan.cpp
+39
-68
src/rt/rust_chan.h
src/rt/rust_chan.h
+3
-3
src/rt/rust_internal.h
src/rt/rust_internal.h
+0
-2
src/rt/rust_kernel.cpp
src/rt/rust_kernel.cpp
+3
-136
src/rt/rust_kernel.h
src/rt/rust_kernel.h
+1
-76
src/rt/rust_message.cpp
src/rt/rust_message.cpp
+0
-125
src/rt/rust_message.h
src/rt/rust_message.h
+0
-135
src/rt/rust_port.cpp
src/rt/rust_port.cpp
+2
-4
src/rt/rust_port.h
src/rt/rust_port.h
+3
-2
src/rt/rust_proxy.h
src/rt/rust_proxy.h
+0
-77
src/rt/rust_scheduler.cpp
src/rt/rust_scheduler.cpp
+8
-31
src/rt/rust_scheduler.h
src/rt/rust_scheduler.h
+3
-10
src/rt/rust_task.cpp
src/rt/rust_task.cpp
+0
-9
src/rt/rust_task.h
src/rt/rust_task.h
+0
-4
src/rt/rust_upcall.cpp
src/rt/rust_upcall.cpp
+2
-4
未找到文件。
mk/rt.mk
浏览文件 @
d1dbb999
...
...
@@ -18,7 +18,6 @@ RUNTIME_CS := rt/sync/timer.cpp \
rt/rust_port.cpp
\
rt/rust_upcall.cpp
\
rt/rust_log.cpp
\
rt/rust_message.cpp
\
rt/rust_timer.cpp
\
rt/circular_buffer.cpp
\
rt/isaac/randport.cpp
\
...
...
@@ -44,9 +43,7 @@ RUNTIME_HDR := rt/globals.h \
rt/rust_scheduler.h
\
rt/rust_task.h
\
rt/rust_task_list.h
\
rt/rust_proxy.h
\
rt/rust_log.h
\
rt/rust_message.h
\
rt/circular_buffer.h
\
rt/util/array_list.h
\
rt/util/indexed_list.h
\
...
...
src/rt/rust.cpp
浏览文件 @
d1dbb999
...
...
@@ -93,7 +93,6 @@ rust_start(uintptr_t main_fn, int argc, char **argv, void* crate_map) {
rust_srv
*
srv
=
new
rust_srv
(
env
);
rust_kernel
*
kernel
=
new
rust_kernel
(
srv
,
env
->
num_sched_threads
);
kernel
->
start
();
rust_task
*
root_task
=
kernel
->
create_task
(
NULL
,
"main"
);
rust_scheduler
*
sched
=
root_task
->
sched
;
command_line_args
*
args
...
...
src/rt/rust_chan.cpp
浏览文件 @
d1dbb999
...
...
@@ -4,7 +4,7 @@
/**
* Create a new rust channel and associate it with the specified port.
*/
rust_chan
::
rust_chan
(
rust_kernel
*
kernel
,
maybe_proxy
<
rust_port
>
*
port
,
rust_chan
::
rust_chan
(
rust_kernel
*
kernel
,
rust_port
*
port
,
size_t
unit_sz
)
:
ref_count
(
1
),
kernel
(
kernel
),
...
...
@@ -29,18 +29,16 @@ rust_chan::~rust_chan() {
/**
* Link this channel with the specified port.
*/
void
rust_chan
::
associate
(
maybe_proxy
<
rust_port
>
*
port
)
{
void
rust_chan
::
associate
(
rust_port
*
port
)
{
this
->
port
=
port
;
if
(
port
->
is_proxy
()
==
false
)
{
scoped_lock
with
(
port
->
referent
()
->
lock
);
KLOG
(
kernel
,
task
,
"associating chan: 0x%"
PRIxPTR
" with port: 0x%"
PRIxPTR
,
this
,
port
);
++
this
->
ref_count
;
this
->
task
=
port
->
referent
()
->
task
;
this
->
task
->
ref
();
this
->
port
->
referent
()
->
chans
.
push
(
this
);
}
scoped_lock
with
(
port
->
lock
);
KLOG
(
kernel
,
task
,
"associating chan: 0x%"
PRIxPTR
" with port: 0x%"
PRIxPTR
,
this
,
port
);
++
this
->
ref_count
;
this
->
task
=
port
->
task
;
this
->
task
->
ref
();
this
->
port
->
chans
.
push
(
this
);
}
bool
rust_chan
::
is_associated
()
{
...
...
@@ -52,19 +50,17 @@ bool rust_chan::is_associated() {
*/
void
rust_chan
::
disassociate
()
{
A
(
kernel
,
port
->
referent
()
->
lock
.
lock_held_by_current_thread
(),
port
->
lock
.
lock_held_by_current_thread
(),
"Port referent lock must be held to call rust_chan::disassociate"
);
A
(
kernel
,
is_associated
(),
"Channel must be associated with a port."
);
if
(
port
->
is_proxy
()
==
false
)
{
KLOG
(
kernel
,
task
,
"disassociating chan: 0x%"
PRIxPTR
" from port: 0x%"
PRIxPTR
,
this
,
port
->
referent
());
--
this
->
ref_count
;
task
->
deref
();
this
->
task
=
NULL
;
port
->
referent
()
->
chans
.
swap_delete
(
this
);
}
KLOG
(
kernel
,
task
,
"disassociating chan: 0x%"
PRIxPTR
" from port: 0x%"
PRIxPTR
,
this
,
port
);
--
this
->
ref_count
;
task
->
deref
();
this
->
task
=
NULL
;
port
->
chans
.
swap_delete
(
this
);
// Delete reference to the port.
port
=
NULL
;
...
...
@@ -74,12 +70,7 @@ void rust_chan::disassociate() {
* Attempt to send data to the associated port.
*/
void
rust_chan
::
send
(
void
*
sptr
)
{
I
(
kernel
,
!
port
->
is_proxy
());
rust_port
*
target_port
=
port
->
referent
();
// TODO: We can probably avoid this lock by using atomic operations in
// circular_buffer.
scoped_lock
with
(
target_port
->
lock
);
scoped_lock
with
(
port
->
lock
);
buffer
.
enqueue
(
sptr
);
...
...
@@ -92,28 +83,17 @@ void rust_chan::send(void *sptr) {
A
(
kernel
,
!
buffer
.
is_empty
(),
"rust_chan::transmit with nothing to send."
);
if
(
port
->
is_proxy
())
{
data_message
::
send
(
buffer
.
peek
(),
buffer
.
unit_sz
,
"send data"
,
task
->
get_handle
(),
port
->
as_proxy
()
->
handle
());
buffer
.
dequeue
(
NULL
);
}
else
{
if
(
target_port
->
task
->
blocked_on
(
target_port
))
{
KLOG
(
kernel
,
comm
,
"dequeued in rendezvous_ptr"
);
buffer
.
dequeue
(
target_port
->
task
->
rendezvous_ptr
);
target_port
->
task
->
rendezvous_ptr
=
0
;
target_port
->
task
->
wakeup
(
target_port
);
return
;
}
if
(
port
->
task
->
blocked_on
(
port
))
{
KLOG
(
kernel
,
comm
,
"dequeued in rendezvous_ptr"
);
buffer
.
dequeue
(
port
->
task
->
rendezvous_ptr
);
port
->
task
->
rendezvous_ptr
=
0
;
port
->
task
->
wakeup
(
port
);
}
return
;
}
rust_chan
*
rust_chan
::
clone
(
rust_task
*
target
)
{
size_t
unit_sz
=
buffer
.
unit_sz
;
maybe_proxy
<
rust_port
>
*
port
=
this
->
port
;
return
new
(
target
->
kernel
,
"cloned chan"
)
rust_chan
(
kernel
,
port
,
unit_sz
);
rust_chan
(
kernel
,
port
,
buffer
.
unit_sz
);
}
/**
...
...
@@ -125,30 +105,21 @@ void rust_chan::destroy() {
"Channel's ref count should be zero."
);
if
(
is_associated
())
{
if
(
port
->
is_proxy
())
{
// Here is a good place to delete the port proxy we allocated
// in upcall_clone_chan.
rust_proxy
<
rust_port
>
*
proxy
=
port
->
as_proxy
();
scoped_lock
with
(
port
->
referent
()
->
lock
);
disassociate
();
delete
proxy
;
}
else
{
// We're trying to delete a channel that another task may be
// reading from. We have two options:
//
// 1. We can flush the channel by blocking in upcall_flush_chan()
// and resuming only when the channel is flushed. The problem
// here is that we can get ourselves in a deadlock if the
// parent task tries to join us.
//
// 2. We can leave the channel in a "dormnat" state by not freeing
// it and letting the receiver task delete it for us instead.
if
(
buffer
.
is_empty
()
==
false
)
{
return
;
}
scoped_lock
with
(
port
->
referent
()
->
lock
);
disassociate
();
// We're trying to delete a channel that another task may be
// reading from. We have two options:
//
// 1. We can flush the channel by blocking in upcall_flush_chan()
// and resuming only when the channel is flushed. The problem
// here is that we can get ourselves in a deadlock if the
// parent task tries to join us.
//
// 2. We can leave the channel in a "dormnat" state by not freeing
// it and letting the receiver task delete it for us instead.
if
(
buffer
.
is_empty
()
==
false
)
{
return
;
}
scoped_lock
with
(
port
->
lock
);
disassociate
();
}
delete
this
;
}
...
...
src/rt/rust_chan.h
浏览文件 @
d1dbb999
...
...
@@ -5,18 +5,18 @@ class rust_chan : public kernel_owned<rust_chan>,
public
rust_cond
{
public:
RUST_REFCOUNTED_WITH_DTOR
(
rust_chan
,
destroy
())
rust_chan
(
rust_kernel
*
kernel
,
maybe_proxy
<
rust_port
>
*
port
,
rust_chan
(
rust_kernel
*
kernel
,
rust_port
*
port
,
size_t
unit_sz
);
~
rust_chan
();
rust_kernel
*
kernel
;
rust_task
*
task
;
maybe_proxy
<
rust_port
>
*
port
;
rust_port
*
port
;
size_t
idx
;
circular_buffer
buffer
;
void
associate
(
maybe_proxy
<
rust_port
>
*
port
);
void
associate
(
rust_port
*
port
);
void
disassociate
();
bool
is_associated
();
...
...
src/rt/rust_internal.h
浏览文件 @
d1dbb999
...
...
@@ -219,9 +219,7 @@ public:
#include "memory_region.h"
#include "rust_srv.h"
#include "rust_log.h"
#include "rust_proxy.h"
#include "rust_kernel.h"
#include "rust_message.h"
#include "rust_scheduler.h"
struct
rust_timer
{
...
...
src/rt/rust_kernel.cpp
浏览文件 @
d1dbb999
#include "rust_internal.h"
#define KLOG_(...) \
#define KLOG_(...)
\
KLOG(this, kern, __VA_ARGS__)
#define KLOG_ERR_(field, ...)
\
#define KLOG_ERR_(field, ...) \
KLOG_LVL(this, field, log_err, __VA_ARGS__)
rust_kernel
::
rust_kernel
(
rust_srv
*
srv
,
size_t
num_threads
)
:
_region
(
srv
,
true
),
_log
(
srv
,
NULL
),
srv
(
srv
),
_interrupt_kernel_loop
(
FALSE
),
num_threads
(
num_threads
),
rval
(
0
),
live_tasks
(
0
),
...
...
@@ -22,15 +21,9 @@ rust_kernel::rust_kernel(rust_srv *srv, size_t num_threads) :
rust_scheduler
*
rust_kernel
::
create_scheduler
(
int
id
)
{
_kernel_lock
.
lock
();
rust_message_queue
*
message_queue
=
new
(
this
,
"rust_message_queue"
)
rust_message_queue
(
srv
,
this
);
rust_srv
*
srv
=
this
->
srv
->
clone
();
rust_scheduler
*
sched
=
new
(
this
,
"rust_scheduler"
)
rust_scheduler
(
this
,
message_queue
,
srv
,
id
);
rust_handle
<
rust_scheduler
>
*
handle
=
internal_get_sched_handle
(
sched
);
message_queue
->
associate
(
handle
);
message_queues
.
append
(
message_queue
);
new
(
this
,
"rust_scheduler"
)
rust_scheduler
(
this
,
srv
,
id
);
KLOG_
(
"created scheduler: "
PTR
", id: %d, index: %d"
,
sched
,
id
,
sched
->
list_index
);
_kernel_lock
.
signal_all
();
...
...
@@ -43,7 +36,6 @@ rust_kernel::destroy_scheduler(rust_scheduler *sched) {
_kernel_lock
.
lock
();
KLOG_
(
"deleting scheduler: "
PTR
", name: %s, index: %d"
,
sched
,
sched
->
name
,
sched
->
list_index
);
sched
->
message_queue
->
disassociate
();
rust_srv
*
srv
=
sched
->
srv
;
delete
sched
;
delete
srv
;
...
...
@@ -65,46 +57,6 @@ void rust_kernel::destroy_schedulers() {
}
}
rust_handle
<
rust_scheduler
>
*
rust_kernel
::
internal_get_sched_handle
(
rust_scheduler
*
sched
)
{
rust_handle
<
rust_scheduler
>
*
handle
=
NULL
;
if
(
_sched_handles
.
get
(
sched
,
&
handle
)
==
false
)
{
handle
=
new
(
this
,
"rust_handle<rust_scheduler"
)
rust_handle
<
rust_scheduler
>
(
this
,
sched
->
message_queue
,
sched
);
_sched_handles
.
put
(
sched
,
handle
);
}
return
handle
;
}
rust_handle
<
rust_task
>
*
rust_kernel
::
get_task_handle
(
rust_task
*
task
)
{
_kernel_lock
.
lock
();
rust_handle
<
rust_task
>
*
handle
=
NULL
;
if
(
_task_handles
.
get
(
task
,
&
handle
)
==
false
)
{
handle
=
new
(
this
,
"rust_handle<rust_task>"
)
rust_handle
<
rust_task
>
(
this
,
task
->
sched
->
message_queue
,
task
);
_task_handles
.
put
(
task
,
handle
);
}
_kernel_lock
.
unlock
();
return
handle
;
}
rust_handle
<
rust_port
>
*
rust_kernel
::
get_port_handle
(
rust_port
*
port
)
{
_kernel_lock
.
lock
();
rust_handle
<
rust_port
>
*
handle
=
NULL
;
if
(
_port_handles
.
get
(
port
,
&
handle
)
==
false
)
{
handle
=
new
(
this
,
"rust_handle<rust_port>"
)
rust_handle
<
rust_port
>
(
this
,
port
->
task
->
sched
->
message_queue
,
port
);
_port_handles
.
put
(
port
,
handle
);
}
_kernel_lock
.
unlock
();
return
handle
;
}
void
rust_kernel
::
log_all_scheduler_state
()
{
for
(
size_t
i
=
0
;
i
<
num_threads
;
++
i
)
{
...
...
@@ -141,73 +93,8 @@ rust_kernel::fatal(char const *fmt, ...) {
va_end
(
args
);
}
void
rust_kernel
::
pump_message_queues
()
{
for
(
size_t
i
=
0
;
i
<
message_queues
.
length
();
i
++
)
{
rust_message_queue
*
queue
=
message_queues
[
i
];
if
(
queue
->
is_associated
()
==
false
)
{
rust_message
*
message
=
NULL
;
while
(
queue
->
dequeue
(
&
message
))
{
message
->
kernel_process
();
delete
message
;
}
}
}
}
void
rust_kernel
::
start_kernel_loop
()
{
_kernel_lock
.
lock
();
while
(
_interrupt_kernel_loop
==
false
)
{
_kernel_lock
.
wait
();
pump_message_queues
();
}
_kernel_lock
.
unlock
();
}
void
rust_kernel
::
run
()
{
KLOG_
(
"started kernel loop"
);
start_kernel_loop
();
KLOG_
(
"finished kernel loop"
);
}
void
rust_kernel
::
terminate_kernel_loop
()
{
KLOG_
(
"terminating kernel loop"
);
_interrupt_kernel_loop
=
true
;
signal_kernel_lock
();
join
();
}
rust_kernel
::~
rust_kernel
()
{
destroy_schedulers
();
terminate_kernel_loop
();
// It's possible that the message pump misses some messages because
// of races, so pump any remaining messages here. By now all domain
// threads should have been joined, so we shouldn't miss any more
// messages.
pump_message_queues
();
KLOG_
(
"freeing handles"
);
free_handles
(
_task_handles
);
KLOG_
(
"..task handles freed"
);
free_handles
(
_port_handles
);
KLOG_
(
"..port handles freed"
);
free_handles
(
_sched_handles
);
KLOG_
(
"..sched handles freed"
);
KLOG_
(
"freeing queues"
);
rust_message_queue
*
queue
=
NULL
;
while
(
message_queues
.
pop
(
&
queue
))
{
K
(
srv
,
queue
->
is_empty
(),
"Kernel message queue should be empty "
"before killing the kernel."
);
delete
queue
;
}
}
void
*
...
...
@@ -224,26 +111,6 @@ void rust_kernel::free(void *mem) {
_region
.
free
(
mem
);
}
template
<
class
T
>
void
rust_kernel
::
free_handles
(
hash_map
<
T
*
,
rust_handle
<
T
>*
>
&
map
)
{
T
*
key
;
rust_handle
<
T
>
*
value
;
while
(
map
.
pop
(
&
key
,
&
value
))
{
KLOG_
(
"...freeing "
PTR
,
value
);
delete
value
;
}
}
void
rust_kernel
::
notify_message_enqueued
(
rust_message_queue
*
queue
,
rust_message
*
message
)
{
// The message pump needs to handle this message if the queue is not
// associated with a domain, therefore signal the message pump.
if
(
queue
->
is_associated
()
==
false
)
{
signal_kernel_lock
();
}
}
void
rust_kernel
::
signal_kernel_lock
()
{
_kernel_lock
.
lock
();
...
...
src/rt/rust_kernel.h
浏览文件 @
d1dbb999
...
...
@@ -2,77 +2,22 @@
#ifndef RUST_KERNEL_H
#define RUST_KERNEL_H
/**
* A handle object for Rust tasks. We need a reference to the message queue
* of the referent's domain which we can safely hang on to since it's a
* kernel object. We use the referent reference as a label we stash in
* messages sent via this proxy.
*/
class
rust_kernel
;
class
rust_message
;
template
<
typename
T
>
class
rust_handle
:
public
rust_cond
,
public
rc_base
<
rust_handle
<
T
>
>
,
public
kernel_owned
<
rust_handle
<
T
>
>
{
public:
rust_kernel
*
kernel
;
rust_message_queue
*
message_queue
;
T
*
_referent
;
T
*
referent
()
{
return
_referent
;
}
rust_handle
(
rust_kernel
*
kernel
,
rust_message_queue
*
message_queue
,
T
*
referent
)
:
kernel
(
kernel
),
message_queue
(
message_queue
),
_referent
(
referent
)
{
// Nop.
}
};
class
rust_task_thread
;
/**
* A global object shared by all thread domains. Most of the data structures
* in this class are synchronized since they are accessed from multiple
* threads.
*/
class
rust_kernel
:
public
rust_thread
{
class
rust_kernel
{
memory_region
_region
;
rust_log
_log
;
public:
rust_srv
*
srv
;
private:
/**
* Task proxy objects are kernel owned handles to Rust objects.
*/
hash_map
<
rust_task
*
,
rust_handle
<
rust_task
>
*>
_task_handles
;
hash_map
<
rust_port
*
,
rust_handle
<
rust_port
>
*>
_port_handles
;
hash_map
<
rust_scheduler
*
,
rust_handle
<
rust_scheduler
>
*>
_sched_handles
;
template
<
class
T
>
void
free_handles
(
hash_map
<
T
*
,
rust_handle
<
T
>*
>
&
map
);
void
run
();
void
start_kernel_loop
();
bool
_interrupt_kernel_loop
;
lock_and_signal
_kernel_lock
;
const
size_t
num_threads
;
void
terminate_kernel_loop
();
void
pump_message_queues
();
rust_handle
<
rust_scheduler
>
*
internal_get_sched_handle
(
rust_scheduler
*
sched
);
array_list
<
rust_scheduler
*>
threads
;
randctx
rctx
;
...
...
@@ -89,20 +34,8 @@ public:
volatile
int
live_tasks
;
/**
* Message queues are kernel objects and are associated with domains.
* Their lifetime is not bound to the lifetime of a domain and in fact
* live on after their associated domain has died. This way we can safely
* communicate with domains that may have died.
*
*/
indexed_list
<
rust_message_queue
>
message_queues
;
struct
rust_env
*
env
;
rust_handle
<
rust_task
>
*
get_task_handle
(
rust_task
*
task
);
rust_handle
<
rust_port
>
*
get_port_handle
(
rust_port
*
port
);
rust_kernel
(
rust_srv
*
srv
,
size_t
num_threads
);
bool
is_deadlocked
();
...
...
@@ -110,14 +43,6 @@ public:
void
signal_kernel_lock
();
void
wakeup_schedulers
();
/**
* Notifies the kernel whenever a message has been enqueued . This gives
* the kernel the opportunity to wake up the message pump thread if the
* message queue is not associated.
*/
void
notify_message_enqueued
(
rust_message_queue
*
queue
,
rust_message
*
message
);
void
log_all_scheduler_state
();
void
log
(
uint32_t
level
,
char
const
*
fmt
,
...);
void
fatal
(
char
const
*
fmt
,
...);
...
...
src/rt/rust_message.cpp
已删除
100644 → 0
浏览文件 @
bc4e9afe
#include "rust_internal.h"
#include "rust_message.h"
rust_message
::
rust_message
(
memory_region
*
region
,
const
char
*
label
,
rust_handle
<
rust_task
>
*
source
,
rust_handle
<
rust_task
>
*
target
)
:
label
(
label
),
region
(
region
),
_source
(
source
),
_target
(
target
)
{
}
rust_message
::~
rust_message
()
{
}
void
rust_message
::
process
()
{
}
void
rust_message
::
kernel_process
()
{
}
notify_message
::
notify_message
(
memory_region
*
region
,
notification_type
type
,
const
char
*
label
,
rust_handle
<
rust_task
>
*
source
,
rust_handle
<
rust_task
>
*
target
)
:
rust_message
(
region
,
label
,
source
,
target
),
type
(
type
)
{
}
data_message
::
data_message
(
memory_region
*
region
,
uint8_t
*
buffer
,
size_t
buffer_sz
,
const
char
*
label
,
rust_handle
<
rust_task
>
*
source
,
rust_handle
<
rust_port
>
*
port
)
:
rust_message
(
region
,
label
,
source
,
NULL
),
_buffer_sz
(
buffer_sz
),
_port
(
port
)
{
_buffer
=
(
uint8_t
*
)
malloc
(
buffer_sz
);
memcpy
(
_buffer
,
buffer
,
buffer_sz
);
}
data_message
::~
data_message
()
{
free
(
_buffer
);
}
/**
* Sends a message to the target task via a proxy. The message is allocated
* in the target task domain along with a proxy which points back to the
* source task.
*/
void
notify_message
::
send
(
notification_type
type
,
const
char
*
label
,
rust_handle
<
rust_task
>
*
source
,
rust_handle
<
rust_task
>
*
target
)
{
memory_region
*
region
=
&
target
->
message_queue
->
region
;
notify_message
*
message
=
new
(
region
,
"notify_message"
)
notify_message
(
region
,
type
,
label
,
source
,
target
);
target
->
message_queue
->
enqueue
(
message
);
}
void
notify_message
::
process
()
{
rust_task
*
task
=
_target
->
referent
();
switch
(
type
)
{
case
KILL
:
// task->ref_count--;
task
->
kill
();
break
;
case
JOIN
:
{
if
(
task
->
dead
()
==
false
)
{
// FIXME: this should be dead code.
assert
(
false
);
}
else
{
send
(
WAKEUP
,
"wakeup"
,
_target
,
_source
);
}
break
;
}
case
WAKEUP
:
task
->
wakeup
(
_source
);
break
;
}
}
void
notify_message
::
kernel_process
()
{
switch
(
type
)
{
case
WAKEUP
:
case
KILL
:
// Ignore.
break
;
case
JOIN
:
send
(
WAKEUP
,
"wakeup"
,
_target
,
_source
);
break
;
}
}
void
data_message
::
send
(
uint8_t
*
buffer
,
size_t
buffer_sz
,
const
char
*
label
,
rust_handle
<
rust_task
>
*
source
,
rust_handle
<
rust_port
>
*
port
)
{
memory_region
*
region
=
&
port
->
message_queue
->
region
;
data_message
*
message
=
new
(
region
,
"data_message"
)
data_message
(
region
,
buffer
,
buffer_sz
,
label
,
source
,
port
);
LOG
(
source
->
referent
(),
comm
,
"==> sending
\"
%s
\"
"
PTR
" in queue "
PTR
,
label
,
message
,
&
port
->
message_queue
);
port
->
message_queue
->
enqueue
(
message
);
}
void
data_message
::
process
()
{
_port
->
referent
()
->
remote_channel
->
send
(
_buffer
);
}
void
data_message
::
kernel_process
()
{
}
rust_message_queue
::
rust_message_queue
(
rust_srv
*
srv
,
rust_kernel
*
kernel
)
:
region
(
srv
,
true
),
kernel
(
kernel
),
sched_handle
(
NULL
)
{
}
//
// Local Variables:
// mode: C++
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
//
src/rt/rust_message.h
已删除
100644 → 0
浏览文件 @
bc4e9afe
#ifndef RUST_MESSAGE_H
#define RUST_MESSAGE_H
/**
* Rust messages are used for inter-thread communication. They are enqueued
* and allocated in the target domain.
*/
/**
* Abstract base class for all message types.
*/
class
rust_message
:
public
region_owned
<
rust_message
>
{
public:
const
char
*
label
;
memory_region
*
region
;
private:
protected:
rust_handle
<
rust_task
>
*
_source
;
rust_handle
<
rust_task
>
*
_target
;
public:
rust_message
(
memory_region
*
region
,
const
char
*
label
,
rust_handle
<
rust_task
>
*
source
,
rust_handle
<
rust_task
>
*
target
);
virtual
~
rust_message
();
/**
* Processes the message in the target domain.
*/
virtual
void
process
();
/**
* Processes the message in the kernel.
*/
virtual
void
kernel_process
();
};
/**
* Notify messages are simple argument-less messages.
*/
class
notify_message
:
public
rust_message
{
public:
enum
notification_type
{
KILL
,
JOIN
,
WAKEUP
};
const
notification_type
type
;
notify_message
(
memory_region
*
region
,
notification_type
type
,
const
char
*
label
,
rust_handle
<
rust_task
>
*
source
,
rust_handle
<
rust_task
>
*
target
);
void
process
();
void
kernel_process
();
/**
* This code executes in the sending domain's thread.
*/
static
void
send
(
notification_type
type
,
const
char
*
label
,
rust_handle
<
rust_task
>
*
source
,
rust_handle
<
rust_task
>
*
target
);
};
/**
* Data messages carry a buffer.
*/
class
data_message
:
public
rust_message
{
private:
uint8_t
*
_buffer
;
size_t
_buffer_sz
;
rust_handle
<
rust_port
>
*
_port
;
public:
data_message
(
memory_region
*
region
,
uint8_t
*
buffer
,
size_t
buffer_sz
,
const
char
*
label
,
rust_handle
<
rust_task
>
*
source
,
rust_handle
<
rust_port
>
*
port
);
virtual
~
data_message
();
void
process
();
void
kernel_process
();
/**
* This code executes in the sending domain's thread.
*/
static
void
send
(
uint8_t
*
buffer
,
size_t
buffer_sz
,
const
char
*
label
,
rust_handle
<
rust_task
>
*
source
,
rust_handle
<
rust_port
>
*
port
);
};
class
rust_message_queue
:
public
lock_free_queue
<
rust_message
*>
,
public
kernel_owned
<
rust_message_queue
>
{
public:
memory_region
region
;
rust_kernel
*
kernel
;
rust_handle
<
rust_scheduler
>
*
sched_handle
;
int32_t
list_index
;
rust_message_queue
(
rust_srv
*
srv
,
rust_kernel
*
kernel
);
void
associate
(
rust_handle
<
rust_scheduler
>
*
sched_handle
)
{
this
->
sched_handle
=
sched_handle
;
}
/**
* The Rust domain relinquishes control to the Rust kernel.
*/
void
disassociate
()
{
this
->
sched_handle
=
NULL
;
}
/**
* Checks if a Rust domain is responsible for draining the message queue.
*/
bool
is_associated
()
{
return
this
->
sched_handle
!=
NULL
;
}
void
enqueue
(
rust_message
*
message
)
{
lock_free_queue
<
rust_message
*>::
enqueue
(
message
);
kernel
->
notify_message_enqueued
(
this
,
message
);
}
};
//
// Local Variables:
// mode: C++
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
//
#endif
/* RUST_MESSAGE_H */
src/rt/rust_port.cpp
浏览文件 @
d1dbb999
...
...
@@ -2,7 +2,7 @@
#include "rust_port.h"
rust_port
::
rust_port
(
rust_task
*
task
,
size_t
unit_sz
)
:
maybe_proxy
<
rust_port
>
(
this
),
kernel
(
task
->
kernel
),
task
(
task
),
:
ref_count
(
1
),
kernel
(
task
->
kernel
),
task
(
task
),
unit_sz
(
unit_sz
),
writers
(
task
),
chans
(
task
)
{
LOG
(
task
,
comm
,
...
...
@@ -17,11 +17,9 @@ rust_port::rust_port(rust_task *task, size_t unit_sz)
rust_port
::~
rust_port
()
{
LOG
(
task
,
comm
,
"~rust_port 0x%"
PRIxPTR
,
(
uintptr_t
)
this
);
// log_state();
// Disassociate channels from this port.
while
(
chans
.
is_empty
()
==
false
)
{
scoped_lock
with
(
referent
()
->
lock
);
scoped_lock
with
(
lock
);
rust_chan
*
chan
=
chans
.
peek
();
chan
->
disassociate
();
...
...
src/rt/rust_port.h
浏览文件 @
d1dbb999
#ifndef RUST_PORT_H
#define RUST_PORT_H
class
rust_port
:
public
maybe_proxy
<
rust_port
>
,
public
kernel_owned
<
rust_port
>
{
class
rust_port
:
public
kernel_owned
<
rust_port
>
,
public
rust_cond
{
public:
RUST_REFCOUNTED
(
rust_port
);
rust_kernel
*
kernel
;
rust_task
*
task
;
size_t
unit_sz
;
...
...
src/rt/rust_proxy.h
已删除
100644 → 0
浏览文件 @
bc4e9afe
#ifndef RUST_PROXY_H
#define RUST_PROXY_H
/**
* A proxy object is a wrapper for remote objects. Proxy objects are domain
* owned and provide a way distinguish between local and remote objects.
*/
template
<
typename
T
>
struct
rust_proxy
;
/**
* The base class of all objects that may delegate.
*/
template
<
typename
T
>
struct
maybe_proxy
:
public
rc_base
<
T
>
,
public
rust_cond
{
protected:
T
*
_referent
;
public:
maybe_proxy
(
T
*
referent
)
:
_referent
(
referent
)
{
}
T
*
referent
()
{
return
(
T
*
)
_referent
;
}
bool
is_proxy
()
{
return
_referent
!=
this
;
}
rust_proxy
<
T
>
*
as_proxy
()
{
return
(
rust_proxy
<
T
>
*
)
this
;
}
T
*
as_referent
()
{
return
(
T
*
)
this
;
}
};
template
<
typename
T
>
class
rust_handle
;
/**
* A proxy object that delegates to another.
*/
template
<
typename
T
>
struct
rust_proxy
:
public
maybe_proxy
<
T
>
{
private:
bool
_strong
;
rust_handle
<
T
>
*
_handle
;
public:
rust_proxy
(
rust_handle
<
T
>
*
handle
)
:
maybe_proxy
<
T
>
(
NULL
),
_strong
(
FALSE
),
_handle
(
handle
)
{
}
rust_proxy
(
T
*
referent
)
:
maybe_proxy
<
T
>
(
referent
),
_strong
(
FALSE
),
_handle
(
NULL
)
{
}
rust_handle
<
T
>
*
handle
()
{
return
_handle
;
}
};
class
rust_message_queue
;
struct
rust_task
;
//
// Local Variables:
// mode: C++
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
//
#endif
/* RUST_PROXY_H */
src/rt/rust_scheduler.cpp
浏览文件 @
d1dbb999
...
...
@@ -4,7 +4,6 @@
#include "globals.h"
rust_scheduler
::
rust_scheduler
(
rust_kernel
*
kernel
,
rust_message_queue
*
message_queue
,
rust_srv
*
srv
,
int
id
)
:
interrupt_flag
(
0
),
...
...
@@ -19,7 +18,6 @@ rust_scheduler::rust_scheduler(rust_kernel *kernel,
dead_tasks
(
this
,
"dead"
),
cache
(
this
),
kernel
(
kernel
),
message_queue
(
message_queue
),
id
(
id
),
min_stack_size
(
kernel
->
env
->
min_stack_size
),
env
(
kernel
->
env
)
...
...
@@ -108,21 +106,6 @@ rust_scheduler::reap_dead_tasks(int id) {
}
}
/**
* Drains and processes incoming pending messages.
*/
void
rust_scheduler
::
drain_incoming_message_queue
(
bool
process
)
{
rust_message
*
message
;
while
(
message_queue
->
dequeue
(
&
message
))
{
DLOG
(
this
,
comm
,
"<== receiving
\"
%s
\"
"
PTR
,
message
->
label
,
message
);
if
(
process
)
{
message
->
process
();
}
delete
message
;
}
}
/**
* Schedules a running task for execution. Only running tasks can be
* activated. Blocked tasks have to be unblocked before they can be
...
...
@@ -207,8 +190,6 @@ rust_scheduler::start_main_loop() {
DLOG
(
this
,
dom
,
"worker %d, number_of_live_tasks = %d, total = %d"
,
id
,
number_of_live_tasks
(),
kernel
->
live_tasks
);
drain_incoming_message_queue
(
true
);
rust_task
*
scheduled_task
=
schedule_task
(
id
);
if
(
scheduled_task
==
NULL
)
{
...
...
@@ -259,18 +240,14 @@ rust_scheduler::start_main_loop() {
"terminated scheduler loop, reaping dead tasks ..."
);
while
(
dead_tasks
.
length
()
>
0
)
{
if
(
message_queue
->
is_empty
())
{
DLOG
(
this
,
dom
,
"waiting for %d dead tasks to become dereferenced, "
"scheduler yielding ..."
,
dead_tasks
.
length
());
log_state
();
lock
.
unlock
();
sync
::
yield
();
lock
.
lock
();
}
else
{
drain_incoming_message_queue
(
true
);
}
DLOG
(
this
,
dom
,
"waiting for %d dead tasks to become dereferenced, "
"scheduler yielding ..."
,
dead_tasks
.
length
());
log_state
();
lock
.
unlock
();
sync
::
yield
();
lock
.
lock
();
reap_dead_tasks
(
id
);
}
...
...
src/rt/rust_scheduler.h
浏览文件 @
d1dbb999
...
...
@@ -51,11 +51,8 @@ struct rust_scheduler : public kernel_owned<rust_scheduler>,
rust_kernel
*
kernel
;
int32_t
list_index
;
hash_map
<
rust_task
*
,
rust_proxy
<
rust_task
>
*>
_task_proxies
;
hash_map
<
rust_port
*
,
rust_proxy
<
rust_port
>
*>
_port_proxies
;
// Incoming messages from other domains.
rust_message_queue
*
message_queue
;
hash_map
<
rust_task
*
,
rust_task
*>
_task_proxies
;
hash_map
<
rust_port
*
,
rust_port
*>
_port_proxies
;
const
int
id
;
...
...
@@ -70,17 +67,13 @@ struct rust_scheduler : public kernel_owned<rust_scheduler>,
// Only a pointer to 'name' is kept, so it must live as long as this
// domain.
rust_scheduler
(
rust_kernel
*
kernel
,
rust_message_queue
*
message_queue
,
rust_srv
*
srv
,
int
id
);
rust_scheduler
(
rust_kernel
*
kernel
,
rust_srv
*
srv
,
int
id
);
~
rust_scheduler
();
void
activate
(
rust_task
*
task
);
void
log
(
rust_task
*
task
,
uint32_t
level
,
char
const
*
fmt
,
...);
rust_log
&
get_log
();
void
fail
();
void
drain_incoming_message_queue
(
bool
process
);
rust_crate_cache
*
get_cache
();
size_t
number_of_live_tasks
();
...
...
src/rt/rust_task.cpp
浏览文件 @
d1dbb999
...
...
@@ -76,7 +76,6 @@ rust_task::rust_task(rust_scheduler *sched, rust_task_list *state,
supervisor
(
spawner
),
list_index
(
-
1
),
rendezvous_ptr
(
0
),
handle
(
NULL
),
running_on
(
-
1
),
pinned_on
(
-
1
),
local_region
(
&
sched
->
srv
->
local_region
),
...
...
@@ -464,14 +463,6 @@ rust_task::backtrace() {
#endif
}
rust_handle
<
rust_task
>
*
rust_task
::
get_handle
()
{
if
(
handle
==
NULL
)
{
handle
=
sched
->
kernel
->
get_task_handle
(
this
);
}
return
handle
;
}
bool
rust_task
::
can_schedule
(
int
id
)
{
return
yield_timer
.
has_timed_out
()
&&
...
...
src/rt/rust_task.h
浏览文件 @
d1dbb999
...
...
@@ -80,8 +80,6 @@ public:
// List of tasks waiting for this task to finish.
array_list
<
rust_task
*>
tasks_waiting_to_join
;
rust_handle
<
rust_task
>
*
handle
;
context
ctx
;
// This flag indicates that a worker is either currently running the task
...
...
@@ -157,8 +155,6 @@ public:
// Notify tasks waiting for us that we are about to die.
void
notify_tasks_waiting_to_join
();
rust_handle
<
rust_task
>
*
get_handle
();
frame_glue_fns
*
get_frame_glue_fns
(
uintptr_t
fp
);
rust_crate_cache
*
get_crate_cache
();
...
...
src/rt/rust_upcall.cpp
浏览文件 @
d1dbb999
...
...
@@ -169,9 +169,7 @@ upcall_clone_chan(rust_task *task, rust_task *target,
extern
"C"
CDECL
rust_task
*
upcall_chan_target_task
(
rust_task
*
task
,
rust_chan
*
chan
)
{
LOG_UPCALL_ENTRY
(
task
);
I
(
task
->
sched
,
!
chan
->
port
->
is_proxy
());
return
chan
->
port
->
referent
()
->
task
;
return
chan
->
port
->
task
;
}
extern
"C"
CDECL
void
...
...
@@ -204,9 +202,9 @@ upcall_send(rust_task *task, rust_chan *chan, void *sptr) {
extern
"C"
CDECL
void
upcall_recv
(
rust_task
*
task
,
uintptr_t
*
dptr
,
rust_port
*
port
)
{
LOG_UPCALL_ENTRY
(
task
);
{
scoped_lock
with
(
port
->
lock
);
LOG_UPCALL_ENTRY
(
task
);
LOG
(
task
,
comm
,
"port: 0x%"
PRIxPTR
", dptr: 0x%"
PRIxPTR
", size: 0x%"
PRIxPTR
", chan_no: %d"
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录