Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
b0289f7b
提交
b0289f7b
4月 19, 2012
创建
作者:
David Benjamin
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
When leaves turn into nodes, drive the recursion in update_range
Simplifies the range locking code. Also we don't need that silly struct.
上级
629bd9a9
隐藏空白字符变更
内嵌
并排
正在显示
1 个修改的文件
包含
42 行增加
和
45 行删除
+42
-45
radix.cc
kernel/radix.cc
+42
-45
没有找到文件。
kernel/radix.cc
浏览文件 @
b0289f7b
...
...
@@ -69,8 +69,11 @@ push_down(radix_entry cur, radix_ptr *ptr)
return
cur
;
}
// Runs CB of a set of leaves whose disjoint union is the range
// [start, end)
// Runs |cb| of a set of leaves whose disjoint union is the range
// [start, end). Callback returns the last known state of the
// radix_ptr. It is assumed |cb| does not convert the leaf into a
// node. If |cb| returns an entry_node, we recurse into the node and
// call |cb| on the new subtree.
template
<
class
CB
>
void
update_range
(
radix_entry
cur
,
radix_ptr
*
ptr
,
CB
cb
,
...
...
@@ -88,6 +91,15 @@ update_range(radix_entry cur, radix_ptr *ptr, CB cb,
cur
=
push_down
(
cur
,
ptr
);
}
if
(
cur
.
is_elem
())
{
// If we're here, the target range must completely contain this
// element.
assert
(
start
<=
cur_start
&&
cur_end
<=
end
);
dprintf
(
" -> [%lx, %lx); size = %lx
\n
"
,
cur_start
,
cur_end
,
cur_end
-
cur_start
);
cur
=
cb
(
cur
,
ptr
);
}
// Recurse if we became a node or we already one.
if
(
cur
.
is_node
())
{
// Find the place to start.
if
(
start
<
cur_start
)
...
...
@@ -103,11 +115,6 @@ update_range(radix_entry cur, radix_ptr *ptr, CB cb,
child_start
,
child_start
+
child_size
,
start
,
end
,
level
-
1
);
}
}
else
{
// If we're here, the target range must completely contain this
// element.
assert
(
start
<=
cur_start
&&
cur_end
<=
end
);
cb
(
cur
,
ptr
,
cur_start
,
cur_end
,
level
);
}
}
...
...
@@ -152,45 +159,30 @@ radix::search_lock(u64 start, u64 size)
return
radix_range
(
this
,
start
>>
shift_
,
size
>>
shift_
);
}
// This should be a lambda, but it's awkward for a lambda to call
// itself.
struct
entry_locker
{
u64
start_
;
u64
end_
;
entry_locker
(
u64
start
,
u64
end
)
:
start_
(
start
),
end_
(
end
)
{
}
void
operator
()(
radix_entry
cur
,
radix_ptr
*
ptr
,
u64
cur_start
,
u64
cur_end
,
u32
level
)
const
{
while
(
cur
.
state
()
!=
entry_node
)
{
// Locked -> spin and try again.
if
(
cur
.
state
()
==
entry_locked
)
{
cur
=
ptr
->
load
();
continue
;
}
// Otherwise it's unlocked. Try to load it.
if
(
ptr
->
compare_exchange_weak
(
cur
,
cur
.
with_state
(
entry_locked
)))
{
// Success. Remember the current value and break out.
cur
=
cur
.
with_state
(
entry_locked
);
break
;
}
}
// Someone pushed down. Recurse some more.
if
(
cur
.
state
()
==
entry_node
)
{
update_range
(
cur
,
ptr
,
*
this
,
cur_start
,
cur_end
,
start_
,
end_
,
level
-
1
);
}
else
{
// We managed to lock!
assert
(
cur
.
state
()
==
entry_locked
);
}
}
};
radix_range
::
radix_range
(
radix
*
r
,
u64
start
,
u64
size
)
:
r_
(
r
),
start_
(
start
),
size_
(
size
)
{
u64
end
=
start_
+
size_
;
// Lock the range from left to right.
const
entry_locker
&
cb
=
entry_locker
(
start_
,
end
);
update_range
(
r_
->
root_
.
load
(),
&
r_
->
root_
,
cb
,
0
,
1L
<<
key_bits
,
start_
,
end
);
dprintf
(
"%p: lock [%lx, %lx)
\n
"
,
r_
,
start
,
start
+
size
);
update_range
(
r_
->
root_
.
load
(),
&
r_
->
root_
,
[](
radix_entry
cur
,
radix_ptr
*
ptr
)
->
radix_entry
{
while
(
cur
.
state
()
!=
entry_node
)
{
// Locked -> spin and try again.
if
(
cur
.
state
()
==
entry_locked
)
{
cur
=
ptr
->
load
();
continue
;
}
// Otherwise it's unlocked. Try to load it.
if
(
ptr
->
compare_exchange_weak
(
cur
,
cur
.
with_state
(
entry_locked
)))
{
// Success. Remember the current value and break out.
cur
=
cur
.
with_state
(
entry_locked
);
break
;
}
}
// We either managed a lock or someone turned us into a node.
assert
(
cur
.
state
()
==
entry_node
||
cur
.
state
()
==
entry_locked
);
return
cur
;
},
0
,
1L
<<
key_bits
,
start_
,
end
);
}
radix_range
::~
radix_range
()
...
...
@@ -198,11 +190,14 @@ radix_range::~radix_range()
if
(
!
r_
)
return
;
update_range
(
r_
->
root_
.
load
(),
&
r_
->
root_
,
[](
radix_entry
cur
,
radix_ptr
*
ptr
,
u64
cur_start
,
u64
cur_end
,
u32
level
)
{
dprintf
(
"%p: unlock [%lx, %lx)
\n
"
,
r_
,
start_
,
start_
+
size_
);
update_range
(
r_
->
root_
.
load
(),
&
r_
->
root_
,
[](
radix_entry
cur
,
radix_ptr
*
ptr
)
->
radix_entry
{
do
{
// It had better still be locked.
assert
(
cur
.
state
()
==
entry_locked
);
}
while
(
!
ptr
->
compare_exchange_weak
(
cur
,
cur
.
with_state
(
entry_unlocked
)));
// Not a node, but let's return what it wants anyway.
return
cur
.
with_state
(
entry_unlocked
);
},
0
,
1L
<<
key_bits
,
start_
,
start_
+
size_
);
}
...
...
@@ -211,20 +206,22 @@ radix_range::replace(u64 start, u64 size, radix_elem *val)
{
start
=
start
>>
r_
->
shift_
;
size
=
size
>>
r_
->
shift_
;
dprintf
(
"%p: replace: [%lx, %lx) with %p
\n
"
,
r_
,
start
,
start
+
size
,
val
);
assert
(
start
>=
start_
);
assert
(
start
+
size
<=
start_
+
size_
);
update_range
(
r_
->
root_
.
load
(),
&
r_
->
root_
,
[
val
](
radix_entry
cur
,
radix_ptr
*
ptr
,
u64
cur_start
,
u64
cur_end
,
u32
level
)
{
dprintf
(
" -> [%lx, %lx); size = %lx
\n
"
,
cur_start
,
cur_end
,
cur_end
-
cur_start
);
dprintf
(
"%p: replace: [%lx, %lx) with %p
\n
"
,
r_
,
start
,
start
+
size
,
val
);
update_range
(
r_
->
root_
.
load
(),
&
r_
->
root_
,
[
val
](
radix_entry
cur
,
radix_ptr
*
ptr
)
->
radix_entry
{
do
{
assert
(
cur
.
state
()
==
entry_locked
);
}
while
(
!
ptr
->
compare_exchange_weak
(
cur
,
radix_entry
(
val
,
entry_locked
)));
if
(
val
)
val
->
incref
();
// cur is now the old value.
if
(
!
cur
.
is_null
())
cur
.
elem
()
->
decref
();
// Not a node, but let's return what it wants anyway.
return
radix_entry
(
val
,
entry_locked
);
},
0
,
1L
<<
key_bits
,
start
,
start
+
size
);
}
...
...
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论