Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
b85fe01b
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,发现更多精彩内容 >>
提交
b85fe01b
编写于
1月 25, 2014
作者:
B
bors
浏览文件
操作
浏览文件
下载
差异文件
auto merge of #11725 : derekchiang/rust/add-barrier, r=alexcrichton
上级
60260b6d
a937d187
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
95 addition
and
0 deletion
+95
-0
src/libextra/sync.rs
src/libextra/sync.rs
+95
-0
未找到文件。
src/libextra/sync.rs
浏览文件 @
b85fe01b
...
...
@@ -27,6 +27,8 @@
use
std
::
util
;
use
std
::
util
::
NonCopyable
;
use
arc
::
MutexArc
;
/****************************************************************************
* Internals
****************************************************************************/
...
...
@@ -682,6 +684,67 @@ impl<'a> RWLockReadMode<'a> {
pub
fn
read
<
U
>
(
&
self
,
blk
:
||
->
U
)
->
U
{
blk
()
}
}
/// A barrier enables multiple tasks to synchronize the beginning
/// of some computation.
/// ```rust
/// use extra::sync::Barrier;
///
/// let barrier = Barrier::new(10);
/// 10.times(|| {
/// let c = barrier.clone();
/// // The same messages will be printed together.
/// // You will NOT see any interleaving.
/// do spawn {
/// println!("before wait");
/// c.wait();
/// println!("after wait");
/// }
/// });
/// ```
#[deriving(Clone)]
pub
struct
Barrier
{
priv
arc
:
MutexArc
<
BarrierState
>
,
priv
num_tasks
:
uint
,
}
// The inner state of a double barrier
struct
BarrierState
{
priv
count
:
uint
,
priv
generation_id
:
uint
,
}
impl
Barrier
{
/// Create a new barrier that can block a given number of tasks.
pub
fn
new
(
num_tasks
:
uint
)
->
Barrier
{
Barrier
{
arc
:
MutexArc
::
new
(
BarrierState
{
count
:
0
,
generation_id
:
0
,
}),
num_tasks
:
num_tasks
,
}
}
/// Block the current task until a certain number of tasks is waiting.
pub
fn
wait
(
&
self
)
{
self
.arc
.access_cond
(|
state
,
cond
|
{
let
local_gen
=
state
.generation_id
;
state
.count
+=
1
;
if
state
.count
<
self
.num_tasks
{
// We need a while loop to guard against spurious wakeups.
// http://en.wikipedia.org/wiki/Spurious_wakeup
while
local_gen
==
state
.generation_id
&&
state
.count
<
self
.num_tasks
{
cond
.wait
();
}
}
else
{
state
.count
=
0
;
state
.generation_id
+=
1
;
cond
.broadcast
();
}
});
}
}
/****************************************************************************
* Tests
****************************************************************************/
...
...
@@ -693,6 +756,7 @@ mod tests {
use
std
::
cast
;
use
std
::
result
;
use
std
::
task
;
use
std
::
comm
::{
SharedChan
,
Empty
};
/************************************************************************
* Semaphore tests
...
...
@@ -1315,4 +1379,35 @@ fn test_rwlock_downgrade_cant_swap() {
})
})
}
/************************************************************************
* Barrier tests
************************************************************************/
#[test]
fn
test_barrier
()
{
let
barrier
=
Barrier
::
new
(
10
);
let
(
port
,
chan
)
=
SharedChan
::
new
();
9
.times
(||
{
let
c
=
barrier
.clone
();
let
chan
=
chan
.clone
();
do
spawn
{
c
.wait
();
chan
.send
(
true
);
}
});
// At this point, all spawned tasks should be blocked,
// so we shouldn't get anything from the port
assert
!
(
match
port
.try_recv
()
{
Empty
=>
true
,
_
=>
false
,
});
barrier
.wait
();
// Now, the barrier is cleared and we should get data.
9
.times
(||
{
port
.recv
();
});
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录