Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
71aa6b66
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,发现更多精彩内容 >>
提交
71aa6b66
编写于
5月 19, 2013
作者:
B
Brian Anderson
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
core::rt: Move more TLS functionality into local_ptr
上级
97c2fd1a
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
94 addition
and
58 deletion
+94
-58
src/libcore/rt/local_ptr.rs
src/libcore/rt/local_ptr.rs
+89
-7
src/libcore/rt/local_sched.rs
src/libcore/rt/local_sched.rs
+5
-51
未找到文件。
src/libcore/rt/local_ptr.rs
浏览文件 @
71aa6b66
...
...
@@ -8,11 +8,19 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Access to a single thread-local pointer
//! Access to a single thread-local pointer.
//!
//! The runtime will use this for storing ~Task.
//!
//! XXX: Add runtime checks for usage of inconsistent pointer types.
//! and for overwriting an existing pointer.
use
libc
::
c_void
;
use
cast
;
use
ptr
;
use
cell
::
Cell
;
use
option
::{
Option
,
Some
,
None
};
use
unstable
::
finally
::
Finally
;
use
tls
=
rt
::
thread_local_storage
;
/// Initialize the TLS key. Other ops will fail if this isn't executed first.
...
...
@@ -25,14 +33,87 @@ pub fn init_tls_key() {
}
}
pub
fn
tls_key
()
->
tls
::
Key
{
/// Give a pointer to thread-local storage.
///
/// # Safety note
///
/// Does not validate the pointer type.
pub
unsafe
fn
put
<
T
>
(
sched
:
~
T
)
{
let
key
=
tls_key
();
let
void_ptr
:
*
mut
c_void
=
cast
::
transmute
(
sched
);
tls
::
set
(
key
,
void_ptr
);
}
/// Take ownership of a pointer from thread-local storage.
///
/// # Safety note
///
/// Does not validate the pointer type.
pub
unsafe
fn
take
<
T
>
()
->
~
T
{
let
key
=
tls_key
();
let
void_ptr
:
*
mut
c_void
=
tls
::
get
(
key
);
rtassert!
(
void_ptr
.is_not_null
());
let
ptr
:
~
T
=
cast
::
transmute
(
void_ptr
);
tls
::
set
(
key
,
ptr
::
mut_null
());
return
ptr
;
}
/// Check whether there is a thread-local pointer installed.
pub
fn
exists
()
->
bool
{
unsafe
{
match
maybe_tls_key
()
{
Some
(
key
)
=>
tls
::
get
(
key
)
.is_not_null
(),
None
=>
false
}
}
}
/// Borrow the thread-local scheduler from thread-local storage.
/// While the scheduler is borrowed it is not available in TLS.
///
/// # Safety note
///
/// Does not validate the pointer type.
pub
unsafe
fn
borrow
<
T
>
(
f
:
&
fn
(
&
mut
T
))
{
let
mut
value
=
take
();
// XXX: Need a different abstraction from 'finally' here to avoid unsafety
let
unsafe_ptr
=
cast
::
transmute_mut_region
(
&
mut
*
value
);
let
value_cell
=
Cell
(
value
);
do
(||
{
f
(
unsafe_ptr
);
})
.finally
{
put
(
value_cell
.take
());
}
}
/// Borrow a mutable reference to the thread-local Scheduler
///
/// # Safety Note
///
/// Because this leaves the Scheduler in thread-local storage it is possible
/// For the Scheduler pointer to be aliased
pub
unsafe
fn
unsafe_borrow
<
T
>
()
->
*
mut
T
{
let
key
=
tls_key
();
let
mut
void_sched
:
*
mut
c_void
=
tls
::
get
(
key
);
rtassert!
(
void_sched
.is_not_null
());
{
let
sched
:
*
mut
*
mut
c_void
=
&
mut
void_sched
;
let
sched
:
*
mut
~
T
=
sched
as
*
mut
~
T
;
let
sched
:
*
mut
T
=
&
mut
**
sched
;
return
sched
;
}
}
fn
tls_key
()
->
tls
::
Key
{
match
maybe_tls_key
()
{
Some
(
key
)
=>
key
,
None
=>
abort!
(
"runtime tls key not initialized"
)
}
}
pub
fn
maybe_tls_key
()
->
Option
<
tls
::
Key
>
{
fn
maybe_tls_key
()
->
Option
<
tls
::
Key
>
{
unsafe
{
let
key
:
*
mut
c_void
=
rust_get_rt_tls_key
();
let
key
:
&
mut
tls
::
Key
=
cast
::
transmute
(
key
);
...
...
@@ -55,9 +136,10 @@ pub fn maybe_tls_key() -> Option<tls::Key> {
return
None
;
}
}
}
extern
{
#[fast_ffi]
fn
rust_get_rt_tls_key
()
->
*
mut
c_void
;
extern
{
#[fast_ffi]
fn
rust_get_rt_tls_key
()
->
*
mut
c_void
;
}
}
src/libcore/rt/local_sched.rs
浏览文件 @
71aa6b66
...
...
@@ -25,53 +25,17 @@
#[cfg(test)]
use
rt
::
uv
::
uvio
::
UvEventLoop
;
/// Give the Scheduler to thread-local storage
pub
fn
put
(
sched
:
~
Scheduler
)
{
unsafe
{
let
key
=
local_ptr
::
tls_key
();
let
void_sched
:
*
mut
c_void
=
cast
::
transmute
(
sched
);
tls
::
set
(
key
,
void_sched
);
}
}
pub
fn
put
(
sched
:
~
Scheduler
)
{
unsafe
{
local_ptr
::
put
(
sched
)
}
}
/// Take ownership of the Scheduler from thread-local storage
pub
fn
take
()
->
~
Scheduler
{
unsafe
{
let
key
=
local_ptr
::
tls_key
();
let
void_sched
:
*
mut
c_void
=
tls
::
get
(
key
);
rtassert!
(
void_sched
.is_not_null
());
let
sched
:
~
Scheduler
=
cast
::
transmute
(
void_sched
);
tls
::
set
(
key
,
mut_null
());
return
sched
;
}
}
pub
fn
take
()
->
~
Scheduler
{
unsafe
{
local_ptr
::
take
()
}
}
/// Check whether there is a thread-local Scheduler attached to the running thread
pub
fn
exists
()
->
bool
{
unsafe
{
match
local_ptr
::
maybe_tls_key
()
{
Some
(
key
)
=>
tls
::
get
(
key
)
.is_not_null
(),
None
=>
false
}
}
}
pub
fn
exists
()
->
bool
{
local_ptr
::
exists
()
}
/// Borrow the thread-local scheduler from thread-local storage.
/// While the scheduler is borrowed it is not available in TLS.
pub
fn
borrow
(
f
:
&
fn
(
&
mut
Scheduler
))
{
let
mut
sched
=
take
();
// XXX: Need a different abstraction from 'finally' here to avoid unsafety
unsafe
{
let
unsafe_sched
=
cast
::
transmute_mut_region
(
&
mut
*
sched
);
let
sched
=
Cell
(
sched
);
do
(||
{
f
(
unsafe_sched
);
})
.finally
{
put
(
sched
.take
());
}
}
}
pub
fn
borrow
(
f
:
&
fn
(
&
mut
Scheduler
))
{
unsafe
{
local_ptr
::
borrow
(
f
)
}
}
/// Borrow a mutable reference to the thread-local Scheduler
///
...
...
@@ -79,17 +43,7 @@ pub fn borrow(f: &fn(&mut Scheduler)) {
///
/// Because this leaves the Scheduler in thread-local storage it is possible
/// For the Scheduler pointer to be aliased
pub
unsafe
fn
unsafe_borrow
()
->
*
mut
Scheduler
{
let
key
=
local_ptr
::
tls_key
();
let
mut
void_sched
:
*
mut
c_void
=
tls
::
get
(
key
);
rtassert!
(
void_sched
.is_not_null
());
{
let
sched
:
*
mut
*
mut
c_void
=
&
mut
void_sched
;
let
sched
:
*
mut
~
Scheduler
=
sched
as
*
mut
~
Scheduler
;
let
sched
:
*
mut
Scheduler
=
&
mut
**
sched
;
return
sched
;
}
}
pub
unsafe
fn
unsafe_borrow
()
->
*
mut
Scheduler
{
local_ptr
::
unsafe_borrow
()
}
pub
unsafe
fn
unsafe_borrow_io
()
->
*
mut
IoFactoryObject
{
let
sched
=
unsafe_borrow
();
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录