Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
b9f1f776
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,发现更多精彩内容 >>
提交
b9f1f776
编写于
8月 12, 2011
作者:
E
Eric Holk
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Fixed memory accounting and task stack creation bugs.
上级
2f23405a
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
81 addition
and
35 deletion
+81
-35
src/lib/task.rs
src/lib/task.rs
+3
-0
src/rt/memory_region.cpp
src/rt/memory_region.cpp
+48
-29
src/rt/memory_region.h
src/rt/memory_region.h
+4
-1
src/rt/rust_builtin.cpp
src/rt/rust_builtin.cpp
+18
-3
src/rt/rust_task.cpp
src/rt/rust_task.cpp
+6
-1
src/rt/rustrt.def.in
src/rt/rustrt.def.in
+1
-0
src/test/stdtest/task.rs
src/test/stdtest/task.rs
+1
-1
未找到文件。
src/lib/task.rs
浏览文件 @
b9f1f776
...
...
@@ -21,6 +21,8 @@
fn
start_task
(
id
:
task_id
);
fn
get_task_trampoline
()
->
u32
;
fn
migrate_alloc
(
alloc
:
*
u8
,
target
:
task_id
);
fn
leak
[
@
T
](
thing
:
-
T
);
}
...
...
@@ -104,6 +106,7 @@ fn _spawn(thunk : fn() -> ()) -> task_id {
*
env
=
raw_thunk
.env
;
*
ra
=
rustrt
::
get_task_trampoline
();
rustrt
::
migrate_alloc
(
cast
(
raw_thunk
.env
),
id
);
rustrt
::
start_task
(
id
);
rustrt
::
leak
(
thunk
);
...
...
src/rt/memory_region.cpp
浏览文件 @
b9f1f776
...
...
@@ -4,7 +4,7 @@
// NB: please do not commit code with this uncommented. It's
// hugely expensive and should only be used as a last resort.
//
#define TRACK_ALLOCATIONS
//
#define TRACK_ALLOCATIONS
#define MAGIC 0xbadc0ffe
...
...
@@ -25,13 +25,13 @@ memory_region::memory_region(memory_region *parent) :
}
void
memory_region
::
add_alloc
()
{
_live_allocations
++
;
//
sync::increment(_live_allocations);
//
_live_allocations++;
sync
::
increment
(
_live_allocations
);
}
void
memory_region
::
dec_alloc
()
{
_live_allocations
--
;
//
sync::decrement(_live_allocations);
//
_live_allocations--;
sync
::
decrement
(
_live_allocations
);
}
void
memory_region
::
free
(
void
*
mem
)
{
...
...
@@ -40,21 +40,10 @@ void memory_region::free(void *mem) {
if
(
_synchronized
)
{
_lock
.
lock
();
}
alloc_header
*
alloc
=
get_header
(
mem
);
assert
(
alloc
->
magic
==
MAGIC
);
#ifdef TRACK_ALLOCATIONS
if
(
_allocation_list
[
alloc
->
index
]
!=
alloc
)
{
printf
(
"free: ptr 0x%"
PRIxPTR
" (%s) is not in allocation_list
\n
"
,
(
uintptr_t
)
&
alloc
->
data
,
alloc
->
tag
);
_srv
->
fatal
(
"not in allocation_list"
,
__FILE__
,
__LINE__
,
""
);
}
else
{
// printf("freed index %d\n", index);
_allocation_list
[
alloc
->
index
]
=
NULL
;
}
#endif
if
(
_live_allocations
<
1
)
{
_srv
->
fatal
(
"live_allocs < 1"
,
__FILE__
,
__LINE__
,
""
);
}
dec_alloc
(
);
release_alloc
(
mem
);
_srv
->
free
(
alloc
);
if
(
_synchronized
)
{
_lock
.
unlock
();
}
}
...
...
@@ -90,18 +79,13 @@ memory_region::realloc(void *mem, size_t size) {
void
*
memory_region
::
malloc
(
size_t
size
,
const
char
*
tag
,
bool
zero
)
{
if
(
_synchronized
)
{
_lock
.
lock
();
}
add_alloc
();
size_t
old_size
=
size
;
size
+=
sizeof
(
alloc_header
);
alloc_header
*
mem
=
(
alloc_header
*
)
_srv
->
malloc
(
size
);
mem
->
magic
=
MAGIC
;
mem
->
tag
=
tag
;
#ifdef TRACK_ALLOCATIONS
mem
->
index
=
_allocation_list
.
append
(
mem
);
// printf("malloc: stored %p at index %d\n", mem, index);
#endif
// printf("malloc: ptr 0x%" PRIxPTR " region=%p\n",
// (uintptr_t) mem, this);
mem
->
index
=
-
1
;
claim_alloc
(
mem
->
data
);
if
(
zero
)
{
memset
(
mem
->
data
,
0
,
old_size
);
...
...
@@ -118,27 +102,32 @@ memory_region::calloc(size_t size, const char *tag) {
memory_region
::~
memory_region
()
{
if
(
_synchronized
)
{
_lock
.
lock
();
}
if
(
_live_allocations
==
0
)
{
if
(
_live_allocations
==
0
&&
!
_detailed_leaks
)
{
if
(
_synchronized
)
{
_lock
.
unlock
();
}
return
;
}
char
msg
[
128
];
snprintf
(
msg
,
sizeof
(
msg
),
"leaked memory in rust main loop (%"
PRIuPTR
" objects)"
,
_live_allocations
);
if
(
_live_allocations
>
0
)
{
snprintf
(
msg
,
sizeof
(
msg
),
"leaked memory in rust main loop (%d objects)"
,
_live_allocations
);
}
#ifdef TRACK_ALLOCATIONS
if
(
_detailed_leaks
)
{
unsigned
int
leak_count
=
0
;
for
(
size_t
i
=
0
;
i
<
_allocation_list
.
size
();
i
++
)
{
if
(
_allocation_list
[
i
]
!=
NULL
)
{
alloc_header
*
header
=
(
alloc_header
*
)
_allocation_list
[
i
];
printf
(
"allocation (%s) 0x%"
PRIxPTR
" was not freed
\n
"
,
header
->
tag
,
(
uintptr_t
)
&
header
->
data
);
++
leak_count
;
}
}
assert
(
leak_count
==
_live_allocations
);
}
#endif
if
(
!
_hack_allow_leaks
)
{
if
(
!
_hack_allow_leaks
&&
_live_allocations
>
0
)
{
_srv
->
fatal
(
msg
,
__FILE__
,
__LINE__
,
"%d objects"
,
_live_allocations
);
}
...
...
@@ -150,6 +139,36 @@ memory_region::hack_allow_leaks() {
_hack_allow_leaks
=
true
;
}
void
memory_region
::
release_alloc
(
void
*
mem
)
{
alloc_header
*
alloc
=
get_header
(
mem
);
assert
(
alloc
->
magic
==
MAGIC
);
#ifdef TRACK_ALLOCATIONS
if
(
_allocation_list
[
alloc
->
index
]
!=
alloc
)
{
printf
(
"free: ptr 0x%"
PRIxPTR
" (%s) is not in allocation_list
\n
"
,
(
uintptr_t
)
&
alloc
->
data
,
alloc
->
tag
);
_srv
->
fatal
(
"not in allocation_list"
,
__FILE__
,
__LINE__
,
""
);
}
else
{
// printf("freed index %d\n", index);
_allocation_list
[
alloc
->
index
]
=
NULL
;
alloc
->
index
=
-
1
;
}
#endif
dec_alloc
();
}
void
memory_region
::
claim_alloc
(
void
*
mem
)
{
alloc_header
*
alloc
=
get_header
(
mem
);
assert
(
alloc
->
magic
==
MAGIC
);
#ifdef TRACK_ALLOCATIONS
alloc
->
index
=
_allocation_list
.
append
(
alloc
);
#endif
add_alloc
();
}
//
// Local Variables:
// mode: C++
...
...
src/rt/memory_region.h
浏览文件 @
b9f1f776
...
...
@@ -27,7 +27,7 @@ private:
rust_srv
*
_srv
;
memory_region
*
_parent
;
size_
t
_live_allocations
;
in
t
_live_allocations
;
array_list
<
alloc_header
*>
_allocation_list
;
const
bool
_detailed_leaks
;
const
bool
_synchronized
;
...
...
@@ -48,6 +48,9 @@ public:
// to not kill the entire process, which the test runner needs. Please
// kill with prejudice once unwinding works.
void
hack_allow_leaks
();
void
release_alloc
(
void
*
mem
);
void
claim_alloc
(
void
*
mem
);
};
inline
void
*
operator
new
(
size_t
size
,
memory_region
&
region
,
...
...
src/rt/rust_builtin.cpp
浏览文件 @
b9f1f776
...
...
@@ -289,7 +289,7 @@ task_yield(rust_task *task) {
extern
"C"
CDECL
intptr_t
task_join
(
rust_task
*
task
,
rust_task_id
tid
)
{
// If the other task is already dying, we don't have to wait for it.
smart_ptr
<
rust_task
>
join_task
=
task
->
kernel
->
get_task_by_id
(
tid
);
rust_task
*
join_task
=
task
->
kernel
->
get_task_by_id
(
tid
);
// FIXME: find task exit status and return that.
if
(
!
join_task
)
return
0
;
join_task
->
lock
.
lock
();
...
...
@@ -720,10 +720,11 @@ new_task(rust_task *task) {
extern
"C"
CDECL
registers_t
*
get_task_context
(
rust_task
*
task
,
rust_task_id
id
)
{
registers_t
*
regs
=
&
task
->
kernel
->
get_task_by_id
(
id
)
->
ctx
.
regs
;
rust_task
*
target
=
task
->
kernel
->
get_task_by_id
(
id
);
registers_t
*
regs
=
&
target
->
ctx
.
regs
;
// This next line is a little dangerous.. It means we can only safely call
// this when starting a task.
regs
->
esp
=
ta
sk
->
rust_sp
;
regs
->
esp
=
ta
rget
->
rust_sp
;
return
regs
;
}
...
...
@@ -746,6 +747,20 @@ get_task_trampoline(rust_task *task) {
return
&
task_trampoline
;
}
extern
"C"
CDECL
void
migrate_alloc
(
rust_task
*
task
,
void
*
alloc
,
rust_task_id
tid
)
{
if
(
!
alloc
)
return
;
rust_task
*
target
=
task
->
kernel
->
get_task_by_id
(
tid
);
if
(
target
)
{
task
->
local_region
.
release_alloc
(
alloc
);
target
->
local_region
.
claim_alloc
(
alloc
);
}
else
{
// We couldn't find the target. Maybe we should just free?
task
->
fail
();
}
}
extern
"C"
CDECL
rust_chan
*
clone_chan
(
rust_task
*
task
,
rust_chan
*
chan
)
{
return
chan
->
clone
(
task
);
...
...
src/rt/rust_task.cpp
浏览文件 @
b9f1f776
...
...
@@ -108,8 +108,13 @@ struct spawn_args {
};
extern
"C"
CDECL
void
task_exit
(
void
*
env
,
int
rval
,
rust_task
*
task
)
{
void
task_exit
(
intptr_t
*
env
,
int
rval
,
rust_task
*
task
)
{
LOG
(
task
,
task
,
"task exited with value %d"
,
rval
);
if
(
env
)
{
// free the environment.
I
(
task
->
sched
,
1
==
*
env
);
// the ref count better be 1
task
->
free
(
env
);
}
task
->
die
();
task
->
lock
.
lock
();
task
->
notify_tasks_waiting_to_join
();
...
...
src/rt/rustrt.def.in
浏览文件 @
b9f1f776
...
...
@@ -41,6 +41,7 @@ ivec_reserve_shared
ivec_to_ptr
last_os_error
leak
migrate_alloc
nano_time
new_chan
new_port
...
...
src/test/stdtest/task.rs
浏览文件 @
b9f1f776
...
...
@@ -43,4 +43,4 @@ fn test_lib_spawn() {
fn
test_lib_spawn2
()
{
fn
foo
(
x
:
int
)
{
assert
(
x
==
42
);
}
task
::
_
spawn
(
bind
foo
(
42
));
}
\ No newline at end of file
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录