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 {
#[cfg(target_endian = "big")]
{
x
}
#[cfg(not(target_endian = "big"))]
{
x.swap_bytes()
}
}
//little endian 转换为硬件架构字节序
pub const fn from_le(x: Self) -> Self {
#[cfg(target_endian = "little")]
{
x
}
#[cfg(not(target_endian = "little"))]
{
x.swap_bytes()
}
}
//硬件架构字节序到big endian
pub const fn to_be(self) -> Self { // or not to be?
#[cfg(target_endian = "big")]
{
self
}
#[cfg(not(target_endian = "big"))]
{
self.swap_bytes()
}
}
//硬件架构字节序到little endian
pub const fn to_le(self) -> Self {
#[cfg(target_endian = "little")]
{
self
}
#[cfg(not(target_endian = "little"))]
{
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 }
}
//其他无符号整形的实现,略
...
...
有符号整形数据
与无符号整形数据类似,略。