Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
bcbe622a
提交
bcbe622a
3月 02, 2012
创建
作者:
Nickolai Zeldovich
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix iteration bug; forgot to git add
上级
3e6c70a4
隐藏空白字符变更
内嵌
并排
正在显示
3 个修改的文件
包含
198 行增加
和
4 行删除
+198
-4
radix.hh
include/radix.hh
+88
-0
radix.cc
kernel/radix.cc
+101
-0
vm.cc
kernel/vm.cc
+9
-4
没有找到文件。
include/radix.hh
0 → 100644
浏览文件 @
bcbe622a
#pragma once
/*
* A page-table-like structure for mapping fixed-length keys to void* ptrs.
*/
#include "markptr.hh"
enum
{
bits_per_level
=
9
};
enum
{
key_bits
=
36
};
enum
{
radix_levels
=
(
key_bits
+
bits_per_level
-
1
)
/
bits_per_level
};
class
radix_elem
:
public
rcu_freed
{
private
:
bool
deleted_
;
std
::
atomic
<
u64
>
ref_
;
public
:
radix_elem
()
:
rcu_freed
(
"radix_elem"
),
deleted_
(
false
),
ref_
(
0
)
{}
bool
deleted
()
{
return
deleted_
;
}
void
decref
()
{
if
(
--
ref_
==
0
)
{
deleted_
=
true
;
gc_delayed
(
this
);
}
}
void
incref
()
{
ref_
++
;
}
};
struct
radix_node
{
markptr
<
void
>
ptr
[
1
<<
bits_per_level
];
radix_node
()
{
for
(
int
i
=
0
;
i
<
sizeof
(
ptr
)
/
sizeof
(
ptr
[
0
]);
i
++
)
ptr
[
i
]
=
0
;
}
NEW_DELETE_OPS
(
radix_node
)
};
struct
radix
;
struct
radix_range
{
radix
*
r_
;
u64
start_
;
u64
size_
;
radix_range
(
radix
*
r
,
u64
start
,
u64
size
);
radix_range
(
radix_range
&&
);
~
radix_range
();
void
replace
(
u64
start
,
u64
size
,
radix_elem
*
val
);
radix_range
(
const
radix_range
&
)
=
delete
;
void
operator
=
(
const
radix_range
&
)
=
delete
;
};
struct
radix
{
markptr
<
void
>
root_
;
u32
shift_
;
radix
(
u32
shift
)
:
root_
(
0
),
shift_
(
shift
)
{
root_
.
ptr
()
=
new
radix_node
();
}
radix_elem
*
search
(
u64
key
);
radix_range
search_lock
(
u64
start
,
u64
size
);
NEW_DELETE_OPS
(
radix
)
};
struct
radix_iterator
{
const
radix
*
r_
;
u64
k_
;
radix_iterator
(
const
radix
*
r
,
u64
k
)
:
r_
(
r
),
k_
(
k
)
{}
radix_iterator
&
operator
++
()
{
k_
++
;
return
*
this
;
}
radix_elem
*
operator
*
();
bool
operator
==
(
const
radix_iterator
&
other
)
{
return
r_
==
other
.
r_
&&
k_
==
other
.
k_
;
}
bool
operator
!=
(
const
radix_iterator
&
other
)
{
return
r_
!=
other
.
r_
||
k_
!=
other
.
k_
;
}
};
static
inline
radix_iterator
begin
(
const
radix
&
r
)
{
return
radix_iterator
(
&
r
,
0
);
}
static
inline
radix_iterator
end
(
const
radix
&
r
)
{
return
radix_iterator
(
&
r
,
~
0ULL
);
}
// What we really need is one-past-the-last...
static
inline
radix_iterator
begin
(
const
radix_range
&
rr
)
{
return
radix_iterator
(
rr
.
r_
,
rr
.
start_
);
}
static
inline
radix_iterator
end
(
const
radix_range
&
rr
)
{
return
radix_iterator
(
rr
.
r_
,
rr
.
start_
+
rr
.
size_
);
}
kernel/radix.cc
0 → 100644
浏览文件 @
bcbe622a
#include "types.h"
#include "atomic.hh"
#include "spinlock.h"
#include "kernel.hh"
#include "cpputil.hh"
#include "radix.hh"
template
<
class
CB
>
void
descend
(
u64
key
,
markptr
<
void
>
*
n
,
u32
level
,
CB
cb
)
{
// for now, we only support exact multiples of bits_per_level
assert
(
key_bits
==
bits_per_level
*
radix_levels
);
assert
(
n
);
void
*
v
=
n
->
ptr
();
if
(
v
==
0
)
{
radix_node
*
new_rn
=
new
radix_node
();
if
(
n
->
ptr
().
cmpxch_update
(
&
v
,
(
void
*
)
new_rn
))
v
=
new_rn
;
else
delete
new_rn
;
}
radix_node
*
rn
=
(
radix_node
*
)
v
;
u64
idx
=
key
>>
(
bits_per_level
*
level
);
idx
&=
(
1
<<
bits_per_level
)
-
1
;
markptr
<
void
>
*
vptr
=
&
rn
->
ptr
[
idx
];
if
(
level
==
0
)
cb
(
vptr
);
else
descend
(
key
,
vptr
,
level
-
1
,
cb
);
}
radix_elem
*
radix
::
search
(
u64
key
)
{
radix_elem
*
result
=
0
;
descend
(
key
>>
shift_
,
&
root_
,
radix_levels
-
1
,
[
&
result
](
markptr
<
void
>
*
v
)
{
result
=
(
radix_elem
*
)
v
->
ptr
().
load
();
});
return
result
;
}
radix_range
radix
::
search_lock
(
u64
start
,
u64
size
)
{
return
radix_range
(
this
,
start
>>
shift_
,
size
>>
shift_
);
}
radix_range
::
radix_range
(
radix
*
r
,
u64
start
,
u64
size
)
:
r_
(
r
),
start_
(
start
),
size_
(
size
)
{
for
(
u64
k
=
start_
;
k
!=
start_
+
size_
;
k
++
)
descend
(
k
,
&
r_
->
root_
,
radix_levels
-
1
,
[](
markptr
<
void
>
*
v
)
{
while
(
!
v
->
mark
().
xchg
(
true
))
;
// spin
});
}
radix_range
::~
radix_range
()
{
if
(
!
r_
)
return
;
for
(
u64
k
=
start_
;
k
!=
start_
+
size_
;
k
++
)
descend
(
k
,
&
r_
->
root_
,
radix_levels
-
1
,
[](
markptr
<
void
>
*
v
)
{
v
->
mark
()
=
false
;
});
}
void
radix_range
::
replace
(
u64
start
,
u64
size
,
radix_elem
*
val
)
{
start
=
start
>>
r_
->
shift_
;
size
=
size
>>
r_
->
shift_
;
assert
(
start
>=
start_
);
assert
(
start
+
size
<=
start_
+
size_
);
for
(
u64
k
=
start
;
k
!=
start
+
size
;
k
++
)
descend
(
k
,
&
r_
->
root_
,
radix_levels
-
1
,
[
val
](
markptr
<
void
>
*
v
)
{
void
*
cur
=
v
->
ptr
().
load
();
while
(
!
v
->
ptr
().
cmpxch_update
(
&
cur
,
val
))
;
// spin
val
->
incref
();
if
(
cur
)
((
radix_elem
*
)
cur
)
->
decref
();
});
}
radix_elem
*
radix_iterator
::
operator
*
()
{
radix_elem
*
result
=
0
;
descend
(
k_
,
(
markptr
<
void
>*
)
&
r_
->
root_
,
radix_levels
-
1
,
[
&
result
](
markptr
<
void
>
*
v
)
{
result
=
(
radix_elem
*
)
v
->
ptr
().
load
();
});
return
result
;
}
kernel/vm.cc
浏览文件 @
bcbe622a
...
@@ -221,9 +221,11 @@ vmap::copy(int share)
...
@@ -221,9 +221,11 @@ vmap::copy(int share)
for
(
auto
r
:
cr
)
{
for
(
auto
r
:
cr
)
{
#endif
#endif
#if VM_RADIX
#if VM_RADIX
void
*
last
=
0
;
for
(
auto
r
:
rx
)
{
for
(
auto
r
:
rx
)
{
if
(
!
r
)
if
(
!
r
||
r
==
last
)
continue
;
continue
;
last
=
r
;
#endif
#endif
vma
*
e
=
(
vma
*
)
r
;
vma
*
e
=
(
vma
*
)
r
;
...
@@ -235,6 +237,9 @@ vmap::copy(int share)
...
@@ -235,6 +237,9 @@ vmap::copy(int share)
if
(
e
->
va_type
!=
COW
)
{
if
(
e
->
va_type
!=
COW
)
{
vma
*
repl
=
new
vma
(
this
,
e
->
vma_start
,
e
->
vma_end
,
COW
,
e
->
n
);
vma
*
repl
=
new
vma
(
this
,
e
->
vma_start
,
e
->
vma_end
,
COW
,
e
->
n
);
replace_vma
(
e
,
repl
);
replace_vma
(
e
,
repl
);
#if VM_RADIX
last
=
repl
;
#endif
updatepages
(
pml4
,
e
->
vma_start
,
e
->
vma_end
,
[](
atomic
<
pme_t
>*
p
)
{
updatepages
(
pml4
,
e
->
vma_start
,
e
->
vma_end
,
[](
atomic
<
pme_t
>*
p
)
{
for
(;;)
{
for
(;;)
{
pme_t
v
=
p
->
load
();
pme_t
v
=
p
->
load
();
...
@@ -264,13 +269,13 @@ vmap::copy(int share)
...
@@ -264,13 +269,13 @@ vmap::copy(int share)
#if VM_RADIX
#if VM_RADIX
auto
span
=
nm
->
rx
.
search_lock
(
ne
->
vma_start
,
ne
->
vma_end
-
ne
->
vma_start
);
auto
span
=
nm
->
rx
.
search_lock
(
ne
->
vma_start
,
ne
->
vma_end
-
ne
->
vma_start
);
#endif
#endif
for
(
auto
x
__attribute__
((
unused
))
:
span
)
{
for
(
auto
x
:
span
)
{
#if VM_RADIX
#if VM_RADIX
if
(
!
x
)
if
(
!
x
)
continue
;
continue
;
#endif
#endif
cprintf
(
"non-empty span
: %p (orig 0x%lx--0x%lx)
\n
"
,
cprintf
(
"non-empty span
0x%lx--0x%lx in %p: %p
\n
"
,
x
,
ne
->
vma_start
,
ne
->
vma_end
);
ne
->
vma_start
,
ne
->
vma_end
,
&
nm
->
rx
,
x
);
assert
(
0
);
/* span must be empty */
assert
(
0
);
/* span must be empty */
}
}
#if VM_CRANGE
#if VM_CRANGE
...
...
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论