RUST的固有(intrinsic)函数库
代码路径:
%USER%.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\intrinsic.rs
intrinsic库函数是指由编译器内置实现的函数,一般如下特点的函数用固有函数:
- 与CPU架构相关性很大,必须利用汇编实现或者利用汇编才能具备最高性能的函数,
- 和编译器密切相关的函数,由编译器来实现最为合适。
上面内存库章节中已经介绍了内存部分的intrinsic库函数,本节对其他部分做简略介绍
intrinsic 原子操作函数
原子操作函数主要用于多核CPU,多线程CPU时对数据的原子操作。intrinsic库中atomic_xxx及atomic_xxx_xxx类型的函数即为原子操作函数。原子操作函数主要用于并发编程中做临界保护,并且是其他临界保护机制的基础,如Mutex,RWlock等。
数学函数及位操作函数
各种整数及浮点的数学函数实现。这一部分放在intrinsic主要是因为现代CPU对浮点计算由很多支持,这些数学函数由汇编语言来实现更具备效率,那就有必要由编译器来内置实现。
intrinsic 指令优化及调试函数
断言类: assert_xxxx 类型的函数
函数栈:caller_location
小结
intrinsic函数库是从编译器层面完成跨CPU架构的一个手段,intrinsic通常被上层的库所封装。但在操作系统编程和框架编程时,仍然会不可避免的需要接触。
RUST数据类型代码分析
原生数据类型,Option类型,Result类型的某些代码是分析其他模块的基础,因此先对这些类型的部分代码做个基础分析。
整形数据类型
代码目录如下:
%USER%.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\num
无符号整形类型相关库代码分析
标准库用宏简化了无符号整形类型的代码部分。 本节给出若干价值较大的函数,如大小端转换,其他代码则做一个分类简略。代码如下:
macro_rules! uint_impl { | |
($SelfT:ty, $ActualT:ident, $SignedT:ident, $BITS:expr, $MaxV:expr, | |
$rot:expr, $rot_op:expr, $rot_result:expr, $swap_op:expr, $swapped:expr, | |
$reversed:expr, $le_bytes:expr, $be_bytes:expr, | |
$to_xe_bytes_doc:expr, $from_xe_bytes_doc:expr) => { | |
pub const MIN: Self = 0; | |
pub const MAX: Self = !0; | |
pub const BITS: u32 = $BITS; | |
//利用intrinsics的位函数完成整数的位操作相关函数,这里仅分析一个,其他请参考标准库手册 | |
pub const fn count_ones(self) -> u32 { | |
intrinsics::ctpop(self as $ActualT) as u32 | |
} | |
//其他位操作函数 | |
... | |
... | |
//内部字节交换,后继大小端变换使用 | |
pub const fn swap_bytes(self) -> Self { | |
intrinsics::bswap(self as $ActualT) as Self | |
} | |
//big endian 到硬件架构字节序 | |
pub const fn from_be(x: Self) -> Self { | |
{ | |
x | |
} | |
{ | |
x.swap_bytes() | |
} | |
} | |
//little endian 转换为硬件架构字节序 | |
pub const fn from_le(x: Self) -> Self { | |
{ | |
x | |
} | |
{ | |
x.swap_bytes() | |
} | |
} | |
//硬件架构字节序到big endian | |
pub const fn to_be(self) -> Self { // or not to be? | |
{ | |
self | |
} | |
{ | |
self.swap_bytes() | |
} | |
} | |
//硬件架构字节序到little endian | |
pub const fn to_le(self) -> Self { | |
{ | |
self | |
} | |
{ | |
self.swap_bytes() | |
} | |
} | |
//获得大端字节序字节数组 | |
pub const fn to_be_bytes(self) -> [u8; mem::size_of::<Self>()] { | |
self.to_be().to_ne_bytes() | |
} | |
//获得小端 | |
pub const fn to_le_bytes(self) -> [u8; mem::size_of::<Self>()] { | |
self.to_le().to_ne_bytes() | |
} | |
//硬件平台字节序 | |
pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] { | |
unsafe { mem::transmute(self) } | |
} | |
//从big endian 字节数组获得类型值 | |
pub const fn from_be_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self { | |
Self::from_be(Self::from_ne_bytes(bytes)) | |
} | |
//从little endian 字节数组获得类型值 | |
pub const fn from_le_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self { | |
Self::from_le(Self::from_ne_bytes(bytes)) | |
} | |
//从硬件架构字节序字节数组获得类型值 | |
pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self { | |
unsafe { mem::transmute(bytes) } | |
} | |
//对溢出做检查的加法运算 | |
//这里每种类型运算都以加法为例,其他诸如减、乘、除、幂次请参考官方标准库手册 | |
pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) { | |
let (a, b) = intrinsics::add_with_overflow(self as $ActualT, rhs as $ActualT); | |
(a as Self, b) | |
} | |
//其他的对溢出做检查的数学运算,略 | |
... | |
... | |
//以边界值取余的加法 | |
pub const fn wrapping_add(self, rhs: Self) -> Self { | |
intrinsics::wrapping_add(self, rhs) | |
} | |
//以边界值取余的其他数学运算方法,略 | |
... | |
... | |
//饱和加法,超过边界值结果为边界值 | |
pub const fn saturating_add(self, rhs: Self) -> Self { | |
intrinsics::saturating_add(self, rhs) | |
} | |
//其他饱和型的数学运算,略 | |
... | |
... | |
//对加法有效性检查的加法运算,如发生溢出,则返回异常 | |
pub const fn checked_add(self, rhs: Self) -> Option<Self> { | |
let (a, b) = self.overflowing_add(rhs); | |
if unlikely!(b) {None} else {Some(a)} | |
} | |
//无检查add, 是 + 符号的默认调用函数。 | |
pub const unsafe fn unchecked_add(self, rhs: Self) -> Self { | |
// 调用者要保证不发生错误 | |
unsafe { intrinsics::unchecked_add(self, rhs) } | |
} | |
//其他对有效性检查的数学运算, 略 | |
... | |
... | |
pub const fn min_value() -> Self { Self::MIN } | |
pub const fn max_value() -> Self { Self::MAX } | |
} | |
impl u8 { | |
//利用宏实现 u8类型的方法 | |
uint_impl! { u8, u8, i8, 8, 255, 2, "0x82", "0xa", "0x12", "0x12", "0x48", "[0x12]", "[0x12]", "", "" } | |
pub const fn is_ascii(&self) -> bool { | |
*self & 128 == 0 | |
} | |
//其他ASCII相关函数,请参考标准库手册,略 | |
... | |
... | |
} | |
//u16 数学函数方法 实现 | |
impl u16 { | |
uint_impl! { u16, u16, i16, 16, 65535, 4, "0xa003", "0x3a", "0x1234", "0x3412", "0x2c48", "[0x34, 0x12]", "[0x12, 0x34]", "", "" } | |
widening_impl! { u16, u32, 16, unsigned } | |
} | |
//其他无符号整形的实现,略 | |
... | |
... |
有符号整形数据
与无符号整形数据类似,略。